Revision: 123 http://geany-plugins.svn.sourceforge.net/geany-plugins/?rev=123&view=rev Author: eht16 Date: 2008-07-16 22:32:34 +0000 (Wed, 16 Jul 2008)
Log Message: ----------- Note: Don't use this revision for productive use! Experimental changes in word retrieval to work better with complex Unicode characters like in Hindi. Use Scintilla's messages for finding word start and end positions instead of my own variant which didn't work well in Hindi. Add a temporary option to switch between Geany's word retrieval method when showing the editor menu or use an alternative one (only for testing). This code is still in testing and should be considered as WIP.
Modified Paths: -------------- trunk/spellcheck/ChangeLog trunk/spellcheck/src/spellcheck.c
Modified: trunk/spellcheck/ChangeLog =================================================================== --- trunk/spellcheck/ChangeLog 2008-07-15 19:14:44 UTC (rev 122) +++ trunk/spellcheck/ChangeLog 2008-07-16 22:32:34 UTC (rev 123) @@ -1,3 +1,17 @@ +2008-07-16 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de> + + * src/spellcheck.c: + Note: Don't use this revision for productive use! + Experimental changes in word retrieval to work better with complex + Unicode characters like in Hindi. + Use Scintilla's messages for finding word start and end positions + instead of my own variant which didn't work well in Hindi. + Add a temporary option to switch between Geany's word retrieval + method when showing the editor menu or use an alternative one + (only for testing). + This code is still in testing and should be considered as WIP. + + 2008-07-15 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
* src/spellcheck.c:
Modified: trunk/spellcheck/src/spellcheck.c =================================================================== --- trunk/spellcheck/src/spellcheck.c 2008-07-15 19:14:44 UTC (rev 122) +++ trunk/spellcheck/src/spellcheck.c 2008-07-16 22:32:34 UTC (rev 123) @@ -35,6 +35,7 @@ #endif
#include <string.h> +#include <ctype.h> #include <enchant.h>
#include "plugindata.h" @@ -65,6 +66,7 @@ gchar *default_language; gboolean use_msgwin; gboolean check_while_typing; + gboolean use_geanys_current_word; gulong signal_id; GPtrArray *dicts; GtkWidget *edit_menu; @@ -205,20 +207,57 @@ }
+/* This is a temporary replacement for Geany's editor_find_current_word() which is not yet + * as good as it should be in reading Unicode words */ +static gchar *get_current_word(GeanyDocument *doc, gint pos_start) +{ + gint wstart, wend; + gchar *word; + gchar c; + + g_message("use internal word retrieval"); + + wstart = p_sci->send_message(doc->editor->sci, SCI_WORDSTARTPOSITION, pos_start, TRUE); + wend = p_sci->send_message(doc->editor->sci, SCI_WORDENDPOSITION, wstart, FALSE); + if (wstart == wend) + return NULL; + c = p_sci->get_char_at(doc->editor->sci, wstart); + + word = g_malloc0(wend - wstart + 1); + /* hopefully it's enough to check for these both */ + if (ispunct(c) || isspace(c)) + { + return NULL; + } + + p_sci->get_text_range(doc->editor->sci, wstart, wend, word); + + return word; +} + + static void on_update_editor_menu(GObject *obj, const gchar *word, gint pos, GeanyDocument *doc, gpointer user_data) { gsize n_suggs, i; gchar **tmp_suggs; + gchar *current_word;
+ g_return_if_fail(doc != NULL && doc->is_valid); + /* hide the submenu in any case, we will reshow it again if we actually found something */ gtk_widget_hide(sc->edit_menu); gtk_widget_hide(sc->edit_menu_sep);
- if (! NZV(word) || enchant_dict_check(sc->dict, word, -1) == 0) + if (sc->use_geanys_current_word) + current_word = g_strdup(word); + else + current_word = get_current_word(doc, pos); + + if (! NZV(current_word) || enchant_dict_check(sc->dict, current_word, -1) == 0) return;
- tmp_suggs = enchant_dict_suggest(sc->dict, word, -1, &n_suggs); + tmp_suggs = enchant_dict_suggest(sc->dict, current_word, -1, &n_suggs);
if (tmp_suggs != NULL) { @@ -227,7 +266,8 @@
clickinfo.pos = pos; clickinfo.doc = doc; - setptr(clickinfo.word, g_strdup(word)); + //~ setptr(clickinfo.word, g_strdup(word)); + setptr(clickinfo.word, current_word);
if (GTK_IS_WIDGET(sc->edit_menu_sub)) gtk_widget_destroy(sc->edit_menu_sub); @@ -253,7 +293,7 @@
image = gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_MENU);
- label = g_strdup_printf(_("Add "%s" to Dictionary"), word); + label = g_strdup_printf(_("Add "%s" to Dictionary"), current_word); menu_item = gtk_image_menu_item_new_with_label(label); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item), image); gtk_container_add(GTK_CONTAINER(sc->edit_menu_sub), menu_item); @@ -278,19 +318,18 @@ }
-static gint check_word(GeanyDocument *doc, gint line_number, GString *str, gint end_pos) +static gint check_word(GeanyDocument *doc, gint line_number, const gchar *word, + gint start_pos, gint end_pos) { gsize j; gsize n_suggs = 0; gchar **suggs; - gchar *word; + GString *str = g_string_sized_new(256);
/* early out if the word is spelled correctly */ - if (enchant_dict_check(sc->dict, str->str, -1) == 0) + if (enchant_dict_check(sc->dict, word, -1) == 0) return 0;
- word = g_strdup(str->str); - g_string_erase(str, 0, str->len); suggs = enchant_dict_suggest(sc->dict, word, -1, &n_suggs);
if (suggs != NULL) @@ -306,19 +345,23 @@ g_string_append_c(str, ' '); }
- p_editor->set_indicator(doc->editor, end_pos - strlen(word), end_pos); + if (start_pos == -1) + start_pos = end_pos - strlen(word); + + p_editor->set_indicator(doc->editor, start_pos, end_pos); if (sc->use_msgwin) p_msgwindow->msg_add(COLOR_RED, line_number + 1, doc, "%s", str->str);
if (suggs != NULL && n_suggs) enchant_dict_free_string_list(sc->dict, suggs); } - g_free(word); + g_string_free(str, TRUE);
return n_suggs; }
+#if 0 static gint process_line(GeanyDocument *doc, gint line_number, const gchar *line) { gint end_pos, char_len; @@ -339,8 +382,7 @@ else if (str->len > 0) { g_string_append_c(str, '\0'); - suggestions_found += check_word(doc, line_number, str, end_pos); - g_string_erase(str, 0, str->len); + suggestions_found += check_word(doc, line_number, str->str, -1, end_pos); }
/* calculate byte len of c and add skip these in line */ @@ -353,7 +395,51 @@ return suggestions_found; }
+#else
+static gint process_line(GeanyDocument *doc, gint line_number, const gchar *line) +{ + gint pos_start, pos_end; + gint wstart, wend; + GString *str = g_string_sized_new(256); + gint suggestions_found = 0; + gchar c; + + pos_start = p_sci->get_position_from_line(doc->editor->sci, line_number); + /* TODO use SCI_GETLINEENDPOSITION */ + pos_end = p_sci->get_position_from_line(doc->editor->sci, line_number + 1); + + while (pos_start < pos_end) + { + wstart = p_sci->send_message(doc->editor->sci, SCI_WORDSTARTPOSITION, pos_start, TRUE); + wend = p_sci->send_message(doc->editor->sci, SCI_WORDENDPOSITION, wstart, FALSE); + if (wstart == wend) + break; + c = p_sci->get_char_at(doc->editor->sci, wstart); + /* hopefully it's enough to check for these both */ + if (ispunct(c) || isspace(c)) + { + pos_start++; + continue; + } + + /* ensure the string has enough allocated memory */ + if (str->len < (guint)(wend - wstart)) + g_string_set_size(str, wend - wstart); + + p_sci->get_text_range(doc->editor->sci, wstart, wend, str->str); + + suggestions_found += check_word(doc, line_number, str->str, wstart, wend); + + pos_start = wend + 1; + } + + g_string_free(str, TRUE); + return suggestions_found; +} +#endif + + static void check_document(GeanyDocument *doc) { gchar *line; @@ -375,6 +461,8 @@ p_msgwindow->msg_add(COLOR_BLUE, -1, NULL, _("Checking file "%s" (lines %d to %d using %s):"), DOC_FILENAME(doc), first_line + 1, last_line + 1, dict_string); + g_message("Checking file "%s" (lines %d to %d using %s):", + DOC_FILENAME(doc), first_line + 1, last_line + 1, dict_string); } else { @@ -383,6 +471,7 @@ if (sc->use_msgwin) p_msgwindow->msg_add(COLOR_BLUE, -1, NULL, _("Checking file "%s" (using %s):"), DOC_FILENAME(doc), dict_string); + g_message("Checking file "%s" (using %s):", DOC_FILENAME(doc), dict_string); } g_free(dict_string);
@@ -594,10 +683,14 @@ sc->use_msgwin = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( g_object_get_data(G_OBJECT(dialog), "check_msgwin"))));
+ sc->use_geanys_current_word = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( + g_object_get_data(G_OBJECT(dialog), "check_current_word")))); + g_key_file_load_from_file(config, sc->config_file, G_KEY_FILE_NONE, NULL); g_key_file_set_string(config, "spellcheck", "language", sc->default_language); g_key_file_set_boolean(config, "spellcheck", "check_while_typing", sc->check_while_typing); g_key_file_set_boolean(config, "spellcheck", "use_msgwin", sc->use_msgwin); + g_key_file_set_boolean(config, "spellcheck", "use_geanys_current_word", sc->use_geanys_current_word);
if (! g_file_test(config_dir, G_FILE_TEST_IS_DIR) && p_utils->mkdir(config_dir, TRUE) != 0) { @@ -696,6 +789,7 @@ sc->check_while_typing = p_utils->get_setting_boolean(config, "spellcheck", "check_while_typing", FALSE); sc->use_msgwin = p_utils->get_setting_boolean(config, "spellcheck", "use_msgwin", FALSE); + sc->use_geanys_current_word = p_utils->get_setting_boolean(config, "spellcheck", "use_geanys_current_word", TRUE); g_key_file_free(config);
locale_init(); @@ -729,7 +823,7 @@
GtkWidget *plugin_configure(GtkDialog *dialog) { - GtkWidget *label, *vbox, *combo, *check_type, *check_msgwin; + GtkWidget *label, *vbox, *combo, *check_type, *check_msgwin, *check_current_word; guint i;
vbox = gtk_vbox_new(FALSE, 6); @@ -743,6 +837,11 @@ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_msgwin), sc->use_msgwin); gtk_box_pack_start(GTK_BOX(vbox), check_msgwin, FALSE, FALSE, 3);
+ check_current_word = gtk_check_button_new_with_label( + _("In the right-click menu, retrieve the current word from Geany?")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_current_word), sc->use_geanys_current_word); + gtk_box_pack_start(GTK_BOX(vbox), check_current_word, FALSE, FALSE, 3); + label = gtk_label_new(_("Language to use for the spell check:")); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 3); @@ -766,6 +865,7 @@ g_object_set_data(G_OBJECT(dialog), "combo", combo); g_object_set_data(G_OBJECT(dialog), "check_type", check_type); g_object_set_data(G_OBJECT(dialog), "check_msgwin", check_msgwin); + g_object_set_data(G_OBJECT(dialog), "check_current_word", check_current_word); g_signal_connect(dialog, "response", G_CALLBACK(on_configure_response), NULL);
gtk_widget_show_all(vbox);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
plugins-commits@lists.geany.org