From ac107802fdd508ecaa6fd44cc56d2ff1cdc3f9b6 Mon Sep 17 00:00:00 2001 From: Sebastien Helleu Date: Sat, 18 Oct 2008 16:03:16 +0200 Subject: Aspell plugin is born again --- src/plugins/CMakeLists.txt | 4 +- src/plugins/aspell/CMakeLists.txt | 5 +- src/plugins/aspell/Makefile.am | 7 +- src/plugins/aspell/aspell-config.c | 338 ++++++ src/plugins/aspell/aspell-config.h | 43 + src/plugins/aspell/aspell-speller.c | 237 +++++ src/plugins/aspell/aspell-speller.h | 41 + src/plugins/aspell/aspell.c | 1942 ++++++++++++++--------------------- src/plugins/aspell/aspell.h | 170 +-- src/plugins/charset/charset.c | 12 +- src/plugins/demo/demo.c | 6 +- src/plugins/irc/irc-command.c | 2 +- src/plugins/irc/irc-ignore.c | 4 +- src/plugins/logger/logger-config.h | 2 - src/plugins/scripts/script.c | 2 +- 15 files changed, 1452 insertions(+), 1363 deletions(-) create mode 100644 src/plugins/aspell/aspell-config.c create mode 100644 src/plugins/aspell/aspell-config.h create mode 100644 src/plugins/aspell/aspell-speller.c create mode 100644 src/plugins/aspell/aspell-speller.h (limited to 'src/plugins') diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index b9b9e97db..a3ef91c8d 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -31,13 +31,13 @@ IF(NOT DISABLE_ALIAS) ADD_SUBDIRECTORY( alias ) ENDIF(NOT DISABLE_ALIAS) -IF(ENABLE_ASPELL) +IF(NOT DISABLE_ASPELL) # Check for aspell libraries FIND_PACKAGE(Aspell) IF(ASPELL_FOUND) ADD_SUBDIRECTORY( aspell ) ENDIF(ASPELL_FOUND) -ENDIF(ENABLE_ASPELL) +ENDIF(NOT DISABLE_ASPELL) IF(NOT DISABLE_CHARSET) # Check for iconv support. diff --git a/src/plugins/aspell/CMakeLists.txt b/src/plugins/aspell/CMakeLists.txt index 7104243d8..d8f31d51c 100644 --- a/src/plugins/aspell/CMakeLists.txt +++ b/src/plugins/aspell/CMakeLists.txt @@ -14,7 +14,10 @@ # along with this program. If not, see . # -ADD_LIBRARY(aspell MODULE aspell.c aspell.h) +ADD_LIBRARY(aspell MODULE +aspell.c aspell.h +aspell-config.c aspell-config.h +aspell-speller.c aspell-speller.h) SET_TARGET_PROPERTIES(aspell PROPERTIES PREFIX "") IF(ASPELL_FOUND) diff --git a/src/plugins/aspell/Makefile.am b/src/plugins/aspell/Makefile.am index 893632111..595cb97ac 100644 --- a/src/plugins/aspell/Makefile.am +++ b/src/plugins/aspell/Makefile.am @@ -20,6 +20,11 @@ libdir = ${weechat_libdir}/plugins lib_LTLIBRARIES = aspell.la -aspell_la_SOURCES = aspell.c aspell.h +aspell_la_SOURCES = aspell.c \ + aspell.h \ + aspell-config.c \ + aspell-config.h \ + aspell-speller.c \ + aspell-speller.h aspell_la_LDFLAGS = -module aspell_la_LIBADD = $(ASPELL_LFLAGS) diff --git a/src/plugins/aspell/aspell-config.c b/src/plugins/aspell/aspell-config.c new file mode 100644 index 000000000..b9eee52d7 --- /dev/null +++ b/src/plugins/aspell/aspell-config.c @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2003-2008 by FlashCode + * See README for License detail, AUTHORS for developers list. + * + * 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 3 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, see . + */ + +/* aspell-config.c: aspell configuration options */ + + +#include +#include +#include + +#include "../weechat-plugin.h" +#include "aspell.h" +#include "aspell-config.h" +#include "aspell-speller.h" + + +struct t_config_file *weechat_aspell_config_file = NULL; +struct t_config_section *weechat_aspell_config_section_dict = NULL; + +/* aspell config, look section */ + +struct t_config_option *weechat_aspell_config_look_color; + +/* aspell config, check section */ + +struct t_config_option *weechat_aspell_config_check_commands; +struct t_config_option *weechat_aspell_config_check_default_dict; +struct t_config_option *weechat_aspell_config_check_real_time; +struct t_config_option *weechat_aspell_config_check_word_min_length; + + +char **weechat_aspell_commands_to_check = NULL; +int weechat_aspell_count_commands_to_check = 0; +int *weechat_aspell_length_commands_to_check = NULL; + + +/* + * weechat_aspell_config_change_commands: called when list of commands is + * changed + */ + +void +weechat_aspell_config_change_commands (void *data, + struct t_config_option *option) +{ + char *value; + int i; + + /* make C compiler happy */ + (void) data; + + if (weechat_aspell_commands_to_check) + { + weechat_string_free_exploded (weechat_aspell_commands_to_check); + weechat_aspell_commands_to_check = NULL; + weechat_aspell_count_commands_to_check = 0; + } + + if (weechat_aspell_length_commands_to_check) + { + free (weechat_aspell_length_commands_to_check); + weechat_aspell_length_commands_to_check = NULL; + } + + value = weechat_config_string (option); + if (value && value[0]) + { + weechat_aspell_commands_to_check = weechat_string_explode (value, + ",", 0, 0, + &weechat_aspell_count_commands_to_check); + if (weechat_aspell_count_commands_to_check > 0) + { + weechat_aspell_length_commands_to_check = malloc (weechat_aspell_count_commands_to_check * + sizeof (int)); + for (i = 0; i < weechat_aspell_count_commands_to_check; i++) + { + weechat_aspell_length_commands_to_check[i] = strlen (weechat_aspell_commands_to_check[i]); + } + } + } +} + +/* + * weechat_aspell_config_change_default_dict: called when default dictionary + * is changed + */ + +void +weechat_aspell_config_change_default_dict (void *data, + struct t_config_option *option) +{ + /* make C compiler happy */ + (void) data; + (void) option; + + weechat_aspell_create_spellers (weechat_current_buffer); +} + +/* + * weechat_aspell_config_create_option: set a dictionary for a buffer + */ + +int +weechat_aspell_config_create_option (void *data, + struct t_config_file *config_file, + struct t_config_section *section, + const char *option_name, + const char *value) +{ + struct t_config_option *ptr_option; + int rc; + + /* make C compiler happy */ + (void) data; + + rc = WEECHAT_CONFIG_OPTION_SET_ERROR; + + if (value && value[0]) + weechat_aspell_speller_check_dictionaries (value); + + if (option_name) + { + ptr_option = weechat_config_search_option (config_file, section, + option_name); + if (ptr_option) + { + if (value && value[0]) + rc = weechat_config_option_set (ptr_option, value, 1); + else + { + weechat_config_option_free (ptr_option); + rc = WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE; + } + } + else + { + if (value && value[0]) + { + ptr_option = weechat_config_new_option ( + config_file, section, + option_name, "string", + _("comma separated list of dictionaries to use on this buffer"), + NULL, 0, 0, value, NULL, NULL, NULL, NULL, NULL, NULL); + rc = (ptr_option) ? + WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE : WEECHAT_CONFIG_OPTION_SET_ERROR; + } + else + rc = WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE; + } + } + + if (rc == WEECHAT_CONFIG_OPTION_SET_ERROR) + { + weechat_printf (NULL, + _("%s%s: error creating aspell dictionary \"%s\" => \"%s\""), + weechat_prefix ("error"), ASPELL_PLUGIN_NAME, + option_name, value); + } + else + weechat_aspell_create_spellers (weechat_current_buffer); + + return rc; +} + +/* + * weechat_aspell_config_get_dict: get a dictionary list for a buffer + */ + +struct t_config_option * +weechat_aspell_config_get_dict (const char *name) +{ + return weechat_config_search_option (weechat_aspell_config_file, + weechat_aspell_config_section_dict, + name); +} + +/* + * weechat_aspell_config_set_dict: set a dictionary list for a buffer + */ + +int +weechat_aspell_config_set_dict (const char *name, const char *value) +{ + return weechat_aspell_config_create_option (NULL, + weechat_aspell_config_file, + weechat_aspell_config_section_dict, + name, + value); +} + +/* + * weechat_aspell_config_init: init aspell configuration file + * return: 1 if ok, 0 if error + */ + +int +weechat_aspell_config_init () +{ + struct t_config_section *ptr_section; + + weechat_aspell_config_file = weechat_config_new (ASPELL_CONFIG_NAME, + NULL, NULL); + if (!weechat_aspell_config_file) + return 0; + + /* look */ + ptr_section = weechat_config_new_section (weechat_aspell_config_file, "look", + 0, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); + if (!ptr_section) + { + weechat_config_free (weechat_aspell_config_file); + return 0; + } + + weechat_aspell_config_look_color = weechat_config_new_option ( + weechat_aspell_config_file, ptr_section, + "color", "color", + N_("color used for mispelled words"), + NULL, 0, 0, "lightred", NULL, NULL, NULL, NULL, NULL, NULL); + + /* check */ + ptr_section = weechat_config_new_section (weechat_aspell_config_file, "check", + 0, 0, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); + if (!ptr_section) + { + weechat_config_free (weechat_aspell_config_file); + return 0; + } + + weechat_aspell_config_check_commands = weechat_config_new_option ( + weechat_aspell_config_file, ptr_section, + "commands", "string", + N_("comma separated list of commands for which spell checking is " + "enabled (spell checking is disabled for all other commands)"), + NULL, 0, 0, + "ame,amsg,away,command,cycle,kick,kickban,me,msg,notice,part,query," + "quit,topic", + NULL, NULL, &weechat_aspell_config_change_commands, NULL, NULL, NULL); + weechat_aspell_config_check_default_dict = weechat_config_new_option ( + weechat_aspell_config_file, ptr_section, + "default_dict", "string", + N_("default dictionary (or comma separated list of dictionaries) to " + "use when buffer has no dictionary defined (leave blank to disable " + "aspell on buffers for which you didn't explicitely enabled it)"), + NULL, 0, 0, "", + NULL, NULL, &weechat_aspell_config_change_default_dict, NULL, NULL, NULL); + weechat_aspell_config_check_word_min_length = weechat_config_new_option ( + weechat_aspell_config_file, ptr_section, + "word_min_length", "integer", + N_("minimum length for a word to be spell checked (use 0 to check all " + "words)"), + NULL, 0, INT_MAX, "2", NULL, NULL, NULL, NULL, NULL, NULL); + weechat_aspell_config_check_real_time = weechat_config_new_option ( + weechat_aspell_config_file, ptr_section, + "real_time", "boolean", + N_("real-time spell checking of words (slower, disabled by default: " + "words are checked only if there's delimiter after)"), + NULL, 0, 0, "off", NULL, NULL, NULL, NULL, NULL, NULL); + + ptr_section = weechat_config_new_section (weechat_aspell_config_file, "dict", + 1, 1, + NULL, NULL, + NULL, NULL, + NULL, NULL, + &weechat_aspell_config_create_option, NULL); + if (!ptr_section) + { + weechat_config_free (weechat_aspell_config_file); + return 0; + } + + weechat_aspell_config_section_dict = ptr_section; + + return 1; +} + +/* + * weechat_aspell_config_read: read aspell configuration file + */ + +int +weechat_aspell_config_read () +{ + int rc; + + rc = weechat_config_read (weechat_aspell_config_file); + if (rc == WEECHAT_CONFIG_READ_OK) + { + weechat_aspell_config_change_commands (NULL, + weechat_aspell_config_check_commands); + } + + return rc; +} + +/* + * weechat_aspell_config_write: write aspell configuration file + */ + +int +weechat_aspell_config_write () +{ + return weechat_config_write (weechat_aspell_config_file); +} + +/* + * aspell_config_free: free aspell configuration + */ + +void +weechat_aspell_config_free () +{ + weechat_config_free (weechat_aspell_config_file); + + if (weechat_aspell_commands_to_check) + weechat_string_free_exploded (weechat_aspell_commands_to_check); + if (weechat_aspell_length_commands_to_check) + free (weechat_aspell_length_commands_to_check); +} diff --git a/src/plugins/aspell/aspell-config.h b/src/plugins/aspell/aspell-config.h new file mode 100644 index 000000000..f307d3ff1 --- /dev/null +++ b/src/plugins/aspell/aspell-config.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2003-2008 by FlashCode + * See README for License detail, AUTHORS for developers list. + * + * 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 3 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, see . + */ + + +#ifndef __WEECHAT_ASPELL_CONFIG_H +#define __WEECHAT_ASPELL_CONFIG_H 1 + +#define ASPELL_CONFIG_NAME "aspell" + + +extern struct t_config_option *weechat_aspell_config_look_color; + +extern struct t_config_option *weechat_aspell_config_check_default_dict; +extern struct t_config_option *weechat_aspell_config_check_real_time; +extern struct t_config_option *weechat_aspell_config_check_word_min_length; + +extern char **weechat_aspell_commands_to_check; +extern int weechat_aspell_count_commands_to_check; +extern int *weechat_aspell_length_commands_to_check; + +extern struct t_config_option *weechat_aspell_config_get_dict (const char *name); +extern int weechat_aspell_config_set_dict (const char *name, const char *value); +extern int weechat_aspell_config_init (); +extern int weechat_aspell_config_read (); +extern int weechat_aspell_config_write (); +extern void weechat_aspell_config_free (); + +#endif /* aspell-config.h */ diff --git a/src/plugins/aspell/aspell-speller.c b/src/plugins/aspell/aspell-speller.c new file mode 100644 index 000000000..f066cc64a --- /dev/null +++ b/src/plugins/aspell/aspell-speller.c @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2003-2008 by FlashCode + * See README for License detail, AUTHORS for developers list. + * + * 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 3 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, see . + */ + +/* aspell-speller.c: speller management for aspell plugin */ + + +#include +#include + +#include "../weechat-plugin.h" +#include "aspell.h" +#include "aspell-speller.h" + + +struct t_aspell_speller *weechat_aspell_spellers = NULL; +struct t_aspell_speller *last_weechat_aspell_speller = NULL; + + +/* + * weechat_aspell_speller_exists: return 1 if an aspell dict exists for a lang, + * 0 otherwise + */ + +int +weechat_aspell_speller_exists (const char *lang) +{ + struct AspellConfig *config; + AspellDictInfoList *list; + AspellDictInfoEnumeration *el; + const AspellDictInfo *dict; + int rc; + + rc = 0; + + config = new_aspell_config (); + list = get_aspell_dict_info_list (config); + el = aspell_dict_info_list_elements (list); + + while ((dict = aspell_dict_info_enumeration_next (el))) + { + if (strcmp (dict->name, lang) == 0) + { + rc = 1; + break; + } + } + + delete_aspell_dict_info_enumeration (el); + delete_aspell_config (config); + + return rc; +} + +/* + * weechat_aspell_speller_check_dictionaries: check dictionaries (called when + * user creates/changes dictionaries + * for a buffer) + */ + +void +weechat_aspell_speller_check_dictionaries (const char *dict_list) +{ + char **argv; + int argc, i; + + if (dict_list) + { + argv = weechat_string_explode (dict_list, ",", 0, 0, &argc); + if (argv) + { + for (i = 0; i < argc; i++) + { + if (!weechat_aspell_speller_exists (argv[i])) + { + weechat_printf (NULL, + _("%s: warning: dictionary \"%s\" is not " + "available on your system"), + ASPELL_PLUGIN_NAME, argv[i]); + } + } + weechat_string_free_exploded (argv); + } + } +} + +/* + * weechat_aspell_speller_search: search a speller + */ + +struct t_aspell_speller * +weechat_aspell_speller_search (const char *lang) +{ + struct t_aspell_speller *ptr_speller; + + for (ptr_speller = weechat_aspell_spellers; ptr_speller; + ptr_speller = ptr_speller->next_speller) + { + if (strcmp (ptr_speller->lang, lang) == 0) + return ptr_speller; + } + + /* no speller found */ + return NULL; +} + +/* + * weechat_aspell_speller_new: create and add a new speller instance + */ + +struct t_aspell_speller * +weechat_aspell_speller_new (const char *lang) +{ + struct t_aspell_speller *new_speller; + AspellConfig *config; + AspellCanHaveError *ret; + + if (!lang) + return NULL; + + if (aspell_debug) + { + weechat_printf (NULL, + "%s: creating new speller for lang \"%s\"", + ASPELL_PLUGIN_NAME, lang); + } + + /* create a speller instance for the newly created cell */ + config = new_aspell_config(); + aspell_config_replace (config, "lang", lang); + + ret = new_aspell_speller (config); + + if (aspell_error (ret) != 0) + { + weechat_printf (NULL, + "%s%s: error: %s", + weechat_prefix ("error"), ASPELL_PLUGIN_NAME, + aspell_error_message (ret)); + delete_aspell_config (config); + delete_aspell_can_have_error (ret); + return NULL; + } + + /* create and add a new speller cell */ + new_speller = malloc (sizeof (*new_speller)); + if (!new_speller) + { + weechat_printf (NULL, + _("%s%s: not enough memory to create new speller"), + weechat_prefix ("error"), ASPELL_PLUGIN_NAME); + return NULL; + } + + new_speller->speller = to_aspell_speller (ret); + new_speller->lang = strdup (lang); + + /* add speller to list */ + new_speller->prev_speller = last_weechat_aspell_speller; + new_speller->next_speller = NULL; + if (weechat_aspell_spellers) + last_weechat_aspell_speller->next_speller = new_speller; + else + weechat_aspell_spellers = new_speller; + last_weechat_aspell_speller = new_speller; + + /* free config */ + delete_aspell_config (config); + + return new_speller; +} + +/* + * weechat_aspell_speller_free: remove a speller instance + */ + +void +weechat_aspell_speller_free (struct t_aspell_speller *speller) +{ + if (!speller) + return; + + if (aspell_debug) + { + weechat_printf (NULL, + "%s: removing speller for lang \"%s\"", + ASPELL_PLUGIN_NAME, speller->lang); + } + + /* free data */ + if (speller->speller) + { + aspell_speller_save_all_word_lists (speller->speller); + delete_aspell_speller (speller->speller); + } + if (speller->lang) + free (speller->lang); + + /* remove speller from list */ + if (speller->prev_speller) + (speller->prev_speller)->next_speller = speller->next_speller; + if (speller->next_speller) + (speller->next_speller)->prev_speller = speller->prev_speller; + if (weechat_aspell_spellers == speller) + weechat_aspell_spellers = speller->next_speller; + if (last_weechat_aspell_speller == speller) + last_weechat_aspell_speller = speller->prev_speller; + + free (speller); +} + +/* + * weechat_aspell_speller_free_all: free all spellers + */ + +void +weechat_aspell_speller_free_all () +{ + while (weechat_aspell_spellers) + { + weechat_aspell_speller_free (weechat_aspell_spellers); + } +} diff --git a/src/plugins/aspell/aspell-speller.h b/src/plugins/aspell/aspell-speller.h new file mode 100644 index 000000000..fb6f92bcf --- /dev/null +++ b/src/plugins/aspell/aspell-speller.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2003-2008 by FlashCode + * See README for License detail, AUTHORS for developers list. + * + * 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 3 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, see . + */ + + +#ifndef __WEECHAT_ASPELL_SPELLER_H +#define __WEECHAT_ASPELL_SPELLER_H 1 + +struct t_aspell_speller +{ + AspellSpeller *speller; /* aspell speller */ + char *lang; /* language */ + + struct t_aspell_speller *prev_speller; /* pointer to next speller */ + struct t_aspell_speller *next_speller; /* pointer to previous speller */ +}; + +extern struct t_aspell_speller *weechat_aspell_spellers; + +extern int weechat_aspell_speller_exists (const char *lang); +extern struct t_aspell_speller *weechat_aspell_speller_search (const char *lang); +extern void weechat_aspell_speller_check_dictionaries (const char *dict_list); +extern struct t_aspell_speller *weechat_aspell_speller_new (const char *lang); +extern void weechat_aspell_speller_free (struct t_aspell_speller *speller); +extern void weechat_aspell_speller_free_all (); + +#endif /* aspell-speller.h */ diff --git a/src/plugins/aspell/aspell.c b/src/plugins/aspell/aspell.c index dd302895f..b44f78dea 100644 --- a/src/plugins/aspell/aspell.c +++ b/src/plugins/aspell/aspell.c @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -/* aspell.c: Aspell plugin support for WeeChat */ +/* aspell.c: aspell plugin for WeeChat */ #include @@ -27,1432 +27,1008 @@ #include "../weechat-plugin.h" #include "aspell.h" +#include "aspell-config.h" +#include "aspell-speller.h" -WEECHAT_PLUGIN_NAME("aspell"); +WEECHAT_PLUGIN_NAME(ASPELL_PLUGIN_NAME); WEECHAT_PLUGIN_DESCRIPTION("Aspell plugin for WeeChat"); WEECHAT_PLUGIN_AUTHOR("FlashCode "); WEECHAT_PLUGIN_VERSION(WEECHAT_VERSION); WEECHAT_PLUGIN_WEECHAT_VERSION(WEECHAT_VERSION); -WEECHAT_LICENSE("GPL"); +WEECHAT_PLUGIN_LICENSE("GPL3"); struct t_weechat_plugin *weechat_aspell_plugin = NULL; -#define weechat_plugin weechat_aspell_plugin -aspell_speller_t *aspell_plugin_speller = NULL; -aspell_config_t *aspell_plugin_config = NULL; -aspell_options_t aspell_plugin_options; +int aspell_debug = 0; +char *aspell_last_modifier_string = NULL; /* last str. received by modifier */ +char *aspell_last_modifier_result = NULL; /* last str. built by modifier */ -/* - * weechat_aspell_new_speller : create a new speller cell - */ - -aspell_speller_t * -weechat_aspell_new_speller (void) +/* aspell supported langs (updated on of 2008-10-17) */ +struct t_aspell_code langs_avail[] = { - aspell_speller_t *s; - - s = malloc (sizeof (*s)); - if (!s) - { - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [ERROR] : unable to alloc memory.", _PLUGIN_NAME); - return NULL; - } - - s->speller= NULL; - s->lang = NULL; - s->refs = 0; - s->prev_speller = NULL; - s->next_speller = NULL; - - return s; -} - -/* - * weechat_aspell_free_speller : free a speller cell - */ - -void -weechat_aspell_free_speller (aspell_speller_t *s) + { "af", "Afrikaans" }, + { "am", "Amharic" }, + { "ar", "Arabic" }, + { "az", "Azerbaijani" }, + { "be", "Belarusian" }, + { "bg", "Bulgarian" }, + { "bn", "Bengali" }, + { "br", "Breton" }, + { "ca", "Catalan" }, + { "cs", "Czech" }, + { "csb", "Kashubian" }, + { "cy", "Welsh" }, + { "da", "Danish" }, + { "de", "German" }, + { "de-alt", "German - Old Spelling" }, + { "el", "Greek" }, + { "en", "English" }, + { "eo", "Esperanto" }, + { "es", "Spanish" }, + { "et", "Estonian" }, + { "fa", "Persian" }, + { "fi", "Finnish" }, + { "fo", "Faroese" }, + { "fr", "French" }, + { "fy", "Frisian" }, + { "ga", "Irish" }, + { "gd", "Scottish Gaelic" }, + { "gl", "Galician" }, + { "gu", "Gujarati" }, + { "gv", "Manx Gaelic" }, + { "he", "Hebrew" }, + { "hi", "Hindi" }, + { "hil", "Hiligaynon" }, + { "hr", "Croatian" }, + { "hsb", "Upper Sorbian" }, + { "hu", "Hungarian" }, + { "hy", "Armenian" }, + { "ia", "Interlingua" }, + { "id", "Indonesian" }, + { "is", "Icelandic" }, + { "it", "Italian" }, + { "ku", "Kurdi" }, + { "la", "Latin" }, + { "lt", "Lithuanian" }, + { "lv", "Latvian" }, + { "mg", "Malagasy" }, + { "mi", "Maori" }, + { "mk", "Macedonian" }, + { "ml", "Malayalam" }, + { "mn", "Mongolian" }, + { "mr", "Marathi" }, + { "ms", "Malay" }, + { "mt", "Maltese" }, + { "nb", "Norwegian Bokmal" }, + { "nds", "Low Saxon" }, + { "nl", "Dutch" }, + { "nn", "Norwegian Nynorsk" }, + { "ny", "Chichewa" }, + { "or", "Oriya" }, + { "pa", "Punjabi" }, + { "pl", "Polish" }, + { "pt_BR", "Brazilian Portuguese" }, + { "pt_PT", "Portuguese" }, + { "qu", "Quechua" }, + { "ro", "Romanian" }, + { "ru", "Russian" }, + { "rw", "Kinyarwanda" }, + { "sc", "Sardinian" }, + { "sk", "Slovak" }, + { "sl", "Slovenian" }, + { "sr", "Serbian" }, + { "sv", "Swedish" }, + { "sw", "Swahili" }, + { "ta", "Tamil" }, + { "te", "Telugu" }, + { "tet", "Tetum" }, + { "tk", "Turkmen" }, + { "tl", "Tagalog" }, + { "tn", "Setswana" }, + { "tr", "Turkish" }, + { "uk", "Ukrainian" }, + { "uz", "Uzbek" }, + { "vi", "Vietnamese" }, + { "wa", "Walloon" }, + { "yi", "Yiddish" }, + { "zu", "Zulu" }, + { NULL, NULL} +}; + +struct t_aspell_code countries_avail[] = { - if (s) - { - if (s->speller) - { - aspell_speller_save_all_word_lists (s->speller); - delete_aspell_speller (s->speller); - } - if (s->lang) - free(s->lang); - free(s); - } -} + { "AT", "Austria" }, + { "BR", "Brazil" }, + { "CA", "Canada" }, + { "CH", "Switzerland" }, + { "DE", "Germany" }, + { "FR", "France" }, + { "GB", "Great Britain" }, + { "PT", "Portugal" }, + { "SK", "Slovakia" }, + { "US", "United States of America" }, + { NULL, NULL} +}; + /* - * weechat_aspell_speller_list_search : search a speller cell + * weechat_aspell_debug_cb: callback for "debug" signal */ -aspell_speller_t * -weechat_aspell_speller_list_search (char *lang) +int +weechat_aspell_debug_cb (void *data, const char *signal, const char *type_data, + void *signal_data) { - aspell_speller_t *p, *r = NULL; + /* make C compiler happy */ + (void) data; + (void) signal; - for(p = aspell_plugin_speller; p; p = p->next_speller) + if (strcmp (type_data, WEECHAT_HOOK_SIGNAL_STRING) == 0) { - if (strcmp(p->lang, lang) == 0) - { - r = p; - break; - } + if (weechat_strcasecmp ((char *)signal_data, ASPELL_PLUGIN_NAME) == 0) + { + aspell_debug ^= 1; + if (aspell_debug) + { + weechat_printf (NULL, _("%s: debug enabled"), + ASPELL_PLUGIN_NAME); + } + else + { + weechat_printf (NULL, _("%s: debug disabled"), + ASPELL_PLUGIN_NAME); + } + } } - return r; + return WEECHAT_RC_OK; } /* - * weechat_aspell_speller_list_add : create and add a new speller instance + * weechat_aspell_build_option_name: build option name with a buffer */ -int -weechat_aspell_speller_list_add (char *lang) +char * +weechat_aspell_build_option_name (struct t_gui_buffer *buffer) { - aspell_speller_t *s; - AspellConfig *config; - AspellCanHaveError *ret; - - /* create a speller instance for the newly created cell */ - config = new_aspell_config(); - aspell_config_replace (config, "lang", lang); + char *plugin_name, *name, *option_name; + int length; - ret = new_aspell_speller (config); - - if (aspell_error (ret) != 0) - { - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [ERROR] : %s", - _PLUGIN_NAME, aspell_error_message (ret)); - delete_aspell_config (config); - delete_aspell_can_have_error (ret); - return 0; - } - - /* create and add a new speller cell */ - s = weechat_aspell_new_speller(); - if (!s) - return 0; + if (!buffer) + return NULL; - s->next_speller = aspell_plugin_speller; - if (aspell_plugin_speller) - aspell_plugin_speller->prev_speller = s; - aspell_plugin_speller = s; + plugin_name = weechat_buffer_get_string (buffer, "plugin"); + name = weechat_buffer_get_string (buffer, "name"); - s->lang = strdup (lang); - s->refs = 1; - s->speller = to_aspell_speller (ret); + length = strlen (plugin_name) + 1 + strlen (name) + 1; + option_name = malloc (length); + if (!option_name) + return NULL; - delete_aspell_config (config); + snprintf (option_name, length, "%s.%s", plugin_name, name); - return 1; + return option_name; } /* - * weechat_aspell_speller_list_remove : remove a speller instance + * weechat_aspell_get_dict: get dictionary list for a buffer + * we first try with all arguments, then remove one by + * one to find dict (from specific to general dict) */ -int -weechat_aspell_speller_list_remove(char *lang) +char * +weechat_aspell_get_dict (struct t_gui_buffer *buffer) { - aspell_speller_t *p; - int r = 0; - - if (!aspell_plugin_speller || !lang) - return 0; + char *name, *option_name, *ptr_end; + struct t_config_option *ptr_option; - if (!aspell_plugin_speller->prev_speller - && !aspell_plugin_speller->next_speller) - { - weechat_aspell_free_speller (aspell_plugin_speller); - aspell_plugin_speller = NULL; - return 1; - } - - for(p = aspell_plugin_speller; p; p = p->next_speller) + name = weechat_aspell_build_option_name (buffer); + if (!name) + return NULL; + + option_name = strdup (name); + if (option_name) { - if (strcmp(p->lang, lang) == 0) - { - if (p->prev_speller) - p->prev_speller->next_speller = p->next_speller; - else - aspell_plugin_speller = p->next_speller; - - if (p->next_speller) - p->next_speller->prev_speller = p->prev_speller; - - weechat_aspell_free_speller (p); - r = 1; - break; - } + ptr_end = option_name + strlen (option_name); + while (ptr_end >= option_name) + { + ptr_option = weechat_aspell_config_get_dict (option_name); + if (ptr_option) + { + free (option_name); + free (name); + return weechat_config_string (ptr_option); + } + ptr_end--; + while ((ptr_end >= option_name) && (ptr_end[0] != '.')) + { + ptr_end--; + } + if ((ptr_end >= option_name) && (ptr_end[0] == '.')) + ptr_end[0] = '\0'; + } + ptr_option = weechat_aspell_config_get_dict (option_name); + + free (option_name); + free (name); + + if (ptr_option) + return weechat_config_string (ptr_option); } - return r; + /* nothing found => return default dictionary (if set) */ + if (weechat_config_string (weechat_aspell_config_check_default_dict) + && weechat_config_string (weechat_aspell_config_check_default_dict)[0]) + return weechat_config_string (weechat_aspell_config_check_default_dict); + + /* no default dictionary set */ + return NULL; } /* - * weechat_aspell_new_config : create a new config cell + * weechat_aspell_set_dict: set a dictionary list for a buffer */ -aspell_config_t * -weechat_aspell_new_config (void) +void +weechat_aspell_set_dict (struct t_gui_buffer *buffer, const char *value) { - aspell_config_t *c; + char *name; + + name = weechat_aspell_build_option_name (buffer); + if (!name) + return; - c = malloc (sizeof (*c)); - if (!c) + if (weechat_aspell_config_set_dict (name, value) > 0) { - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [ERROR] : unable to alloc memory.", _PLUGIN_NAME); - return NULL; + if (value && value[0]) + weechat_printf (NULL, "%s: %s => %s", + ASPELL_PLUGIN_NAME, name, value); + else + weechat_printf (NULL, _("%s: %s: removed"), + ASPELL_PLUGIN_NAME, name); } - - c->server = NULL; - c->channel = NULL; - c->speller = NULL; - c->prev_config = NULL; - c->next_config = NULL; - return c; + free (name); } /* - * weechat_aspell_free_config : free a config cell + * weechat_aspell_spellers_already_ok: check if current spellers are already ok + * return 1 if already ok, 0 if spellers + * must be free then created again */ -void -weechat_aspell_free_config (aspell_config_t *c) +int +weechat_aspell_spellers_already_ok (const char *dict_list) { - if (c) + char **argv; + int argc, rc, i; + struct t_aspell_speller *ptr_speller; + + if (!dict_list && !weechat_aspell_spellers) + return 1; + + if (!dict_list || !weechat_aspell_spellers) + return 0; + + rc = 0; + + argv = weechat_string_explode (dict_list, ",", 0, 0, &argc); + if (argv) { - if (c->server) - free(c->server); - if (c->channel) - free(c->channel); - - free(c); + ptr_speller = weechat_aspell_spellers; + for (i = 0; (i < argc) && ptr_speller; i++) + { + if (strcmp (ptr_speller->lang, argv[i]) == 0) + { + rc = 1; + break; + } + ptr_speller = ptr_speller->next_speller; + } + weechat_string_free_exploded (argv); } + + return rc; } /* - * weechat_aspell_config_list_search : search a config cell + * weechat_aspell_create_spellers: create spellers for a buffer */ -aspell_config_t * -weechat_aspell_config_list_search (char *server, char *channel) +void +weechat_aspell_create_spellers (struct t_gui_buffer *buffer) { - aspell_config_t *p, *r = NULL; - - if (!server || !channel) - return NULL; + char *dict_list, **argv; + int argc, i; - for(p = aspell_plugin_config; p; p = p->next_config) + if (buffer) { - if (strcmp(p->server, server) == 0 - && strcmp(p->channel, channel) == 0) - { - r = p; - break; - } + dict_list = weechat_aspell_get_dict (buffer); + if (!weechat_aspell_spellers_already_ok (dict_list)) + { + weechat_aspell_speller_free_all (); + if (dict_list) + { + argv = weechat_string_explode (dict_list, ",", 0, 0, &argc); + if (argv) + { + for (i = 0; i < argc; i++) + { + weechat_aspell_speller_new (argv[i]); + } + weechat_string_free_exploded (argv); + } + } + } } - - return r; } /* - * weechat_aspell_config_list_add : create and add a new config + * weechat_aspell_buffer_switch_cb: callback for "buffer_switch" signel */ int -weechat_aspell_config_list_add (char *server, char *channel) +weechat_aspell_buffer_switch_cb (void *data, const char *signal, + const char *type_data, void *signal_data) { - aspell_config_t *c; - - c = weechat_aspell_new_config(); - if (!c) - return 0; - - c->channel = strdup (channel); - c->server = strdup (server); - - c->next_config = aspell_plugin_config; - if (aspell_plugin_config) - aspell_plugin_config->prev_config = c; - aspell_plugin_config = c; + /* make C compiler happy */ + (void) data; + (void) signal; + (void) type_data; - return 1; -} - -/* - * weechat_aspell_config_list_remove : remove a speller config - */ - -int -weechat_aspell_config_list_remove(char *server, char *channel) -{ - aspell_config_t *p; - int r = 0; - - if (!aspell_plugin_config || !server || !channel) - return 0; - - if (!aspell_plugin_config->prev_config - && !aspell_plugin_config) - { - weechat_aspell_free_config (aspell_plugin_config); - aspell_plugin_config = NULL; - return 1; - } + weechat_aspell_create_spellers (signal_data); - for(p = aspell_plugin_config; p; p = p->next_config) - { - if (strcmp(p->server, server) == 0 - && strcmp(p->channel, channel) == 0) - { - if (p->prev_config) - p->prev_config->next_config = p->next_config; - else - aspell_plugin_config = p->next_config; - - if (p->next_config) - p->next_config->prev_config = p->prev_config; - weechat_aspell_free_config (p); - r = 1; - break; - } - } - - return r; + return WEECHAT_RC_OK; } /* - * weechat_aspell_iso_to_lang : - * convert an aspell iso lang code - * in its english full name + * weechat_aspell_iso_to_lang: convert an aspell iso lang code in its english + * full name * */ char * -weechat_aspell_iso_to_lang (char *code) +weechat_aspell_iso_to_lang (const char *code) { - iso_langs_t *p; - char *l; - - l = NULL; + int i; - for(p = langs_avail; p->code; ++p) + for (i = 0; langs_avail[i].code; i++) { - if (strcmp(p->code, code) == 0) - { - l = strdup(p->name); - break; - } + if (strcmp (langs_avail[i].code, code) == 0) + return strdup (langs_avail[i].name); } - - if (!l) - l = strdup ("Unknown"); - - return l; + + /* lang code not found */ + return strdup ("Unknown"); } /* - * weechat_aspell_iso_to_country : - * convert an aspell iso country - * code in its english full name + * weechat_aspell_iso_to_country: convert an aspell iso country code in its + * english full name */ char * -weechat_aspell_iso_to_country (char *code) +weechat_aspell_iso_to_country (const char *code) { - iso_countries_t *p; - char *c; - - c = NULL; + int i; - for(p = countries_avail; p->code; ++p) + for (i = 0; countries_avail[i].code; i++) { - if (strcmp(p->code, code) == 0) - { - c = strdup(p->name); - break; - } + if (strcmp (countries_avail[i].code, code) == 0) + return strdup (countries_avail[i].name); } - - if (!c) - c = strdup ("Unknown"); - - return c; -} - -/* - * weechat_aspell_speller_exists : - * return 1 if an aspell dict exists - * for a lang, 0 otherwise - */ - -int -weechat_aspell_speller_exists (char *lang) -{ - struct AspellConfig *config; - AspellDictInfoList *l; - AspellDictInfoEnumeration *el; - const AspellDictInfo *di; - int r; - - r = 0; - config = new_aspell_config(); - l = get_aspell_dict_info_list (config); - el = aspell_dict_info_list_elements (l); - di = NULL; - while (( di = aspell_dict_info_enumeration_next (el))) - { - if (strcmp(di->name, lang) == 0) - { - r = 1; - break; - } - } - - delete_aspell_dict_info_enumeration (el); - delete_aspell_config (config); - - return r; + /* country code not found */ + return strdup ("Unknown"); } /* - * weechat_aspell_speller_list_dicts : - * list all aspell dict installed on system and display them + * weechat_aspell_speller_list_dicts: list all aspell dict installed on system + * and display them */ void -weechat_aspell_speller_list_dicts (void) +weechat_aspell_speller_list_dicts () { - char *country, *lang, *p; + char *country, *lang, *pos; char buffer[192]; struct AspellConfig *config; - AspellDictInfoList *l; + AspellDictInfoList *list; AspellDictInfoEnumeration *el; - const AspellDictInfo *di; + const AspellDictInfo *dict; config = new_aspell_config(); - l = get_aspell_dict_info_list (config); - el = aspell_dict_info_list_elements (l); - di = NULL; - - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, "[%s] *** dictionnaries list :", _PLUGIN_NAME); - - while (( di = aspell_dict_info_enumeration_next (el))) - { - country = NULL; - p = strchr (di->code, '_'); - - if (p) - { - *p = '\0'; - lang = weechat_aspell_iso_to_lang ((char*) di->code); - *p = '_'; - country = weechat_aspell_iso_to_country (p+1); - } - else - lang = weechat_aspell_iso_to_lang ((char*) di->code); - - if (strlen (di->jargon) == 0) - { - if (p) - snprintf (buffer, sizeof(buffer), "%-22s %s (%s)", di->name, lang, country); - else - snprintf (buffer, sizeof(buffer), "%-22s %s", di->name, lang); - } - else - { - if (p) - snprintf (buffer, sizeof(buffer), "%-22s %s (%s - %s)", di->name, lang, country, di->jargon); - else - snprintf (buffer, sizeof(buffer), "%-22s %s (%s)", di->name, lang, di->jargon); - } - - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, "[%s] - %s", _PLUGIN_NAME, buffer); - - if (lang) - free (lang); - if (country) - free (country); - } - - delete_aspell_dict_info_enumeration (el); - delete_aspell_config (config); -} - -/* - * weechat_aspell_config_show : display plugin settings - */ - -void -weechat_aspell_config_show (void) -{ - aspell_config_t *p; + list = get_aspell_dict_info_list (config); + el = aspell_dict_info_list_elements (list); - if (!aspell_plugin_config) - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [SHOW] *** No buffers with spellchecking enable", - _PLUGIN_NAME); - else - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [SHOW] *** Spellchecking is active on the following buffers :", - _PLUGIN_NAME); - - for(p = aspell_plugin_config; p; p = p->next_config) - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [SHOW] -> %s@%s with lang '%s'", - _PLUGIN_NAME, p->channel, p->server, p->speller->lang); - - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [SHOW] *** plugin options :", _PLUGIN_NAME); - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [SHOW] -> word-size = %d", - _PLUGIN_NAME, aspell_plugin_options.word_size); - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [SHOW] -> color = %s", - _PLUGIN_NAME, aspell_plugin_options.color_name); - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - aspell_plugin_options.check_sync == 1 - ? "[%s] [SHOW] -> realtime spellchecking is enable" - : "[%s] [SHOW] -> asynchronous spellchecking is enable" - , - _PLUGIN_NAME); -} - -/* - * weechat_aspell_config_addword : adding a word in personnal dictionaries - */ - -int -weechat_aspell_config_addword(char *word) -{ - char *server, *channel; - aspell_config_t *c; - int ret; + weechat_printf (NULL, ""); + weechat_printf (NULL, + /* TRANSLATORS: %s is "aspell" */ + _( "%s dictionnaries list:"), + ASPELL_PLUGIN_NAME); - ret = 0; - channel = weechat_aspell_plugin->get_info (weechat_aspell_plugin, "channel", NULL); - server = weechat_aspell_plugin->get_info (weechat_aspell_plugin, "server", NULL); - - if (!server || !channel) - return 0; - - c = weechat_aspell_config_list_search (server, channel); - if (c) { - if (aspell_speller_add_to_personal ( - c->speller->speller, (const char *) word, strlen(word)) == 1) - ret = 1; + while ((dict = aspell_dict_info_enumeration_next (el))) + { + country = NULL; + pos = strchr (dict->code, '_'); + + if (pos) + { + pos[0] = '\0'; + lang = weechat_aspell_iso_to_lang ((char*)dict->code); + pos[0] = '_'; + country = weechat_aspell_iso_to_country (pos + 1); + } + else + lang = weechat_aspell_iso_to_lang ((char*)dict->code); + + if (strlen (dict->jargon) == 0) + { + if (pos) + { + snprintf (buffer, sizeof (buffer), "%-22s %s (%s)", + dict->name, lang, country); + } + else + { + snprintf (buffer, sizeof (buffer), "%-22s %s", + dict->name, lang); + } + } + else + { + if (pos) + { + snprintf (buffer, sizeof (buffer), "%-22s %s (%s - %s)", + dict->name, lang, country, dict->jargon); + } + else + { + snprintf (buffer, sizeof (buffer), "%-22s %s (%s)", + dict->name, lang, dict->jargon); + } + } + + weechat_printf (NULL, " %s", buffer); + + if (lang) + free (lang); + if (country) + free (country); } - if (ret) - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [ADD-WORD] word '%s' successfully added in your personnal dictionnary", - _PLUGIN_NAME, word); - else - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [ADD-WORD] an error occured while adding word '%s' in your personnal dict", - _PLUGIN_NAME, word); - - if (server) - free (server); - if (channel) - free (channel); - - return ret; + delete_aspell_dict_info_enumeration (el); + delete_aspell_config (config); } /* - * weechat_aspell_config_dump : display debug infos + * weechat_aspell_add_word : add a word in personnal dictionary */ void -weechat_aspell_config_dump (void) +weechat_aspell_add_word (const char *lang, const char *word) { - aspell_config_t *p; - aspell_speller_t *s; - - if (!aspell_plugin_config) - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [DEBUG] [CONFIG] no config", - _PLUGIN_NAME); - - for(p = aspell_plugin_config; p; p = p->next_config) - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [DEBUG] [CONFIG] @%p server='%s' channel='%s' @speller=%p lang='%s' @p=%p @n=%p", - _PLUGIN_NAME, p, p->server, p->channel, p->speller, p->speller->lang, p->prev_config, p->next_config); + struct t_aspell_speller *new_speller, *ptr_speller; - if (!aspell_plugin_speller) - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [DEBUG] [SPELLER] no speller", - _PLUGIN_NAME); - - for(s = aspell_plugin_speller; s; s = s->next_speller) - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [DEBUG] [SPELLER] @%p lang='%s' refs=%d @engine=%p @p=%p @n=%p", - _PLUGIN_NAME, s, s->lang, s->refs, s->speller, s->prev_speller, s->next_speller); -} - -/* - * weechat_aspell_config_enable_for : internal subroutine - */ - -void -weechat_aspell_config_enable_for (char *server, char *channel, char *lang) -{ - aspell_config_t *c; - aspell_speller_t *s; - - if (!weechat_aspell_speller_exists (lang)) + new_speller = NULL; + ptr_speller = weechat_aspell_speller_search (lang); + if (!ptr_speller) { - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [WARN] '%s' dictionary doesn't seems to be available on your system", - _PLUGIN_NAME, lang); - return; - } - - c = weechat_aspell_config_list_search (server, channel); - if (c) - { - c->speller->refs--; - if (c->speller->refs == 0) - weechat_aspell_speller_list_remove (c->speller->lang); - weechat_aspell_config_list_remove (server, channel); + if (!weechat_aspell_speller_exists (lang)) + { + weechat_printf (NULL, + _("%s: error: dictionary \"%s\" is not " + "available on your system"), + ASPELL_PLUGIN_NAME, lang); + return; + } + new_speller = weechat_aspell_speller_new (lang); + if (!new_speller) + return; + ptr_speller = new_speller; } - if (!weechat_aspell_config_list_add (server, channel)) + if (aspell_speller_add_to_personal (ptr_speller->speller, + word, + strlen (word)) == 1) { - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [ERROR] enabling spell checking on %s@%s failed", - _PLUGIN_NAME, channel, server); - return; - } - - s = weechat_aspell_speller_list_search (lang); - - if (!s) { - weechat_aspell_speller_list_add (lang); - s = aspell_plugin_speller; + weechat_printf (NULL, + _("%s: word \"%s\" added to personal dictionary"), + ASPELL_PLUGIN_NAME, word); } else - s->refs++; - - aspell_plugin_config->speller = s; - -} - -/* - * weechat_aspell_config_enable : - * enabling given lang spell checking on current server/channel - */ - -void -weechat_aspell_config_enable (char *lang) -{ - char *channel, *server; - - channel = weechat_aspell_plugin->get_info (weechat_aspell_plugin, "channel", NULL); - server = weechat_aspell_plugin->get_info (weechat_aspell_plugin, "server", NULL); - - if (!server || !channel) { - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [WARN] you are not in a channel", - _PLUGIN_NAME); - return; + weechat_printf (NULL, + _("%s%s: failed to add word to personal " + "dictionary"), + weechat_prefix ("error"), ASPELL_PLUGIN_NAME); } - weechat_aspell_config_enable_for (server, channel, lang); - - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] spell checking '%s' is now active on %s@%s", - _PLUGIN_NAME, lang, channel, server); - - if (channel) - free (channel); - if (server) - free (server); + if (new_speller) + weechat_aspell_speller_free (new_speller); } /* - * weechat_aspell_config_disable : - * disabling spell checking on current server/channel + * weechat_aspell_command_authorized: return 1 if command is authorized for + * spell checking, otherwise 0 */ -void -weechat_aspell_config_disable (void) +int +weechat_aspell_command_authorized (const char *command) { - aspell_config_t *c; - char *channel, *server; + int length_command, i; - channel = weechat_aspell_plugin->get_info (weechat_aspell_plugin, "channel", NULL); - server = weechat_aspell_plugin->get_info (weechat_aspell_plugin, "server", NULL); - - if (!server || !channel) - { - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [WARN] you are not in a channel", - _PLUGIN_NAME, NULL, NULL); - return; - } + if (!command) + return 1; - c = weechat_aspell_config_list_search (server, channel); - if (!c) + length_command = strlen (command); + + for (i = 0; i < weechat_aspell_count_commands_to_check; i++) { - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [WARN] spell checking is not active on %s@%s", - _PLUGIN_NAME, channel, server); - if (channel) - free (channel); - if (server) - free (server); - return; + if ((weechat_aspell_length_commands_to_check[i] == length_command) + && (weechat_strcasecmp (command, + weechat_aspell_commands_to_check[i]) == 0)) + { + /* command is authorized */ + return 1; + } } - c->speller->refs--; - if (c->speller->refs == 0) - weechat_aspell_speller_list_remove (c->speller->lang); - - weechat_aspell_config_list_remove (server, channel); - - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] spell checking is now inactive on %s@%s", - _PLUGIN_NAME, channel, server); - - if (channel) - free (channel); - if (server) - free (server); + /* command is not authorized */ + return 0; } /* - * weechat_aspell_config_set : setting options values + * weechat_aspell_string_strip_punctuation: strip punctuation chars at the + * begining and at the end of a word */ -int -weechat_aspell_config_set(char *option, char *value) +char * +weechat_aspell_string_strip_punctuation (const char *word) { - int c; + const char *ptr_start, *ptr_end; - if (strcmp (option, "word-size") == 0) - { - aspell_plugin_options.word_size = atoi ((value == NULL) ? "" : value); - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [SET] setting %s = %d", - _PLUGIN_NAME, option, aspell_plugin_options.word_size); - } - else if (strcmp (option, "toggle-check-mode") == 0) - { - aspell_plugin_options.check_sync = aspell_plugin_options.check_sync == 1 ? 0 : 1; - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - aspell_plugin_options.check_sync == 1 - ? "[%s] [SET] spellchecking is now set in realtime mode" - : "[%s] [SET] spellchecking is now set in asynchronous mode", - _PLUGIN_NAME, option); - } - else if (strcmp (option, "color") == 0) + if (!word) + return NULL; + + ptr_start = word; + while (ptr_start[0]) { - c = weechat_aspell_plugin->get_irc_color (weechat_aspell_plugin, (value == NULL) ? "" : value); - if (c == -1) - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [SET] setting %s = %s failed : color '%s' is unknown", - _PLUGIN_NAME, option, - (value == NULL) ? "" : value, - (value == NULL) ? "" : value); - else - { - aspell_plugin_options.color = c; - if (aspell_plugin_options.color_name) - free (aspell_plugin_options.color_name); - aspell_plugin_options.color_name = strdup (value); - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, - "[%s] [SET] setting %s = %s", - _PLUGIN_NAME, option, aspell_plugin_options.color_name); - } + if (!ispunct (ptr_start[0])) + break; + ptr_start++; } - else - return 0; - - return 1; -} -/* - * weechat_aspell_config_save : saving plugin config - */ - -int -weechat_aspell_config_save (void) -{ - aspell_config_t *p, *q; - char *servers, *channels, *option; - char **servers_list; - int n, i, s, found; + if (!ptr_start[0]) + return strdup (""); - servers = NULL; - - weechat_aspell_plugin->set_plugin_config (weechat_aspell_plugin, "servers", ""); + ptr_end = ptr_start + strlen (ptr_start) - 1; - for(p = aspell_plugin_config; p; p = p->next_config) + while (ptr_end >= ptr_start) { - servers = weechat_aspell_plugin->get_plugin_config (weechat_aspell_plugin, "servers"); - - if (!servers) - weechat_aspell_plugin->set_plugin_config (weechat_aspell_plugin, "servers", p->server); - else if (strlen (servers) == 0) - { - weechat_aspell_plugin->set_plugin_config (weechat_aspell_plugin, "servers", p->server); - free (servers); - } - else - { - servers_list = weechat_aspell_plugin->explode_string (weechat_aspell_plugin, servers, " ", 0, &s); - if (servers_list) - { - found = 0; - for (i=0; iserver) == 0) - { - found = 1; - break; - } - } - if (found == 0) - { - n = strlen (servers) + strlen (p->server) + 2; - servers = realloc (servers, n); - strcat (servers, " "); - strcat (servers, p->server); - weechat_aspell_plugin->set_plugin_config (weechat_aspell_plugin, "servers", servers); - } - free (servers_list); - } - free (servers); - } - - channels = NULL; - for(q = aspell_plugin_config; q; q = q->next_config) - { - if (strcmp (p->server, q->server) == 0) - { - if (!channels) - channels = strdup (q->channel); - else - { - n = strlen (channels) + strlen (q->channel) + 2; - channels = realloc (channels, n); - strcat (channels, " "); - strcat (channels, q->channel); - } - - n = 7 + strlen (p->server) + strlen (q->channel); - option = malloc (n); - snprintf (option, n, "lang_%s_%s", p->server, q->channel); - weechat_aspell_plugin->set_plugin_config (weechat_aspell_plugin, option, q->speller->lang); - free (option); - } - } - - if (channels) - { - n = 10 + strlen (p->server); - option = malloc (n); - snprintf (option, n, "channels_%s", p->server); - weechat_aspell_plugin->set_plugin_config (weechat_aspell_plugin, option, channels); - free (option); - free (channels); - } + if (!ispunct (ptr_end[0])) + break; + ptr_end--; } - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, "[%s] [SAVE] configuration saved", _PLUGIN_NAME); - return 1; + if (ptr_end < ptr_start) + return strdup (""); + + return weechat_strndup (ptr_start, ptr_end - ptr_start + 1); } /* - * weechat_aspell_config_load : loading plugin config + * weechat_aspell_string_is_url: detect if a word is an url */ -int -weechat_aspell_config_load(void) +int +weechat_aspell_string_is_url (const char *word) { - char *servers, *channels, *lang; - char *option_s, *option_l; - char **servers_list, **channels_list; - int i, j, s, c, n; - - servers = weechat_aspell_plugin->get_plugin_config (weechat_aspell_plugin, "servers"); - if (!servers) - return 0; - - servers_list = weechat_aspell_plugin->explode_string (weechat_aspell_plugin, servers, " ", 0, &s); - - if (servers_list) - { - for (i=0; iget_plugin_config (weechat_aspell_plugin, option_s); - if (channels) - { - channels_list = weechat_aspell_plugin->explode_string (weechat_aspell_plugin, channels, " ", 0, &c); - if (channels_list) - { - for (j=0; jget_plugin_config (weechat_aspell_plugin, option_l); - if (lang) - { - weechat_aspell_config_enable_for (servers_list[i], channels_list[j], lang); - free (lang); - } - free (option_l); - } - weechat_aspell_plugin->free_exploded_string (weechat_aspell_plugin, channels_list); - } - free (channels); - } - free (option_s); - } - - weechat_aspell_plugin->free_exploded_string (weechat_aspell_plugin, servers_list); - } - - weechat_aspell_plugin->print_server (weechat_aspell_plugin, "[%s] [LOAD] configuration loaded", _PLUGIN_NAME); - return 1; + if ((weechat_strncasecmp(word, "http://", 7) == 0) + || (weechat_strncasecmp(word, "https://", 8) == 0) + || (weechat_strncasecmp(word, "ftp://", 6) == 0) + || (weechat_strncasecmp(word, "tftp://", 7) == 0) + || (weechat_strncasecmp(word, "ftps://", 7) == 0) + || (weechat_strncasecmp(word, "ssh://", 6) == 0) + || (weechat_strncasecmp(word, "fish://", 7) == 0) + || (weechat_strncasecmp(word, "dict://", 7) == 0) + || (weechat_strncasecmp(word, "ldap://", 7) == 0) + || (weechat_strncasecmp(word, "file://", 7) == 0) + || (weechat_strncasecmp(word, "telnet://", 9) == 0) + || (weechat_strncasecmp(word, "gopher://", 9) == 0) + || (weechat_strncasecmp(word, "irc://", 6) == 0) + || (weechat_strncasecmp(word, "ircs://", 7) == 0) + || (weechat_strncasecmp(word, "irc6://", 7) == 0) + || (weechat_strncasecmp(word, "irc6s://", 8) == 0) + || (weechat_strncasecmp(word, "cvs://", 6) == 0) + || (weechat_strncasecmp(word, "svn://", 6) == 0) + || (weechat_strncasecmp(word, "svn+ssh://", 10) == 0) + || (weechat_strncasecmp(word, "git://", 6) == 0)) + return 1; + + return 0; } /* - * weechat_aspell_options_save : saving plugin options + * weechat_aspell_string_is_simili_number: detect if a word is made of chars and + * punctuation */ int -weechat_aspell_options_save(void) +weechat_aspell_string_is_simili_number (const char *word) { - char buf[8]; + const char *ptr_word; - snprintf (buf, sizeof(buf), "%d", aspell_plugin_options.word_size); - weechat_aspell_plugin->set_plugin_config (weechat_aspell_plugin, "word-size", buf); + if (!word) + return 0; - snprintf (buf, sizeof(buf), "%d", aspell_plugin_options.check_sync); - weechat_aspell_plugin->set_plugin_config (weechat_aspell_plugin, "check-sync", buf); + ptr_word = word; + while (ptr_word[0]) + { + if (!ispunct (ptr_word[0]) && !isdigit (ptr_word[0])) + return 0; + ptr_word++; + } - weechat_aspell_plugin->set_plugin_config (weechat_aspell_plugin, "color", aspell_plugin_options.color_name); - - weechat_aspell_plugin->print (weechat_aspell_plugin, NULL, NULL, "[%s] [SAVE] options saved", _PLUGIN_NAME); + /* there's only digit or punctuation */ return 1; } /* - * weechat_aspell_options_load : loading plugin options + * weechat_aspell_check_word: spell check a word + * return 1 if word is ok, 0 if word is mispelled */ int -weechat_aspell_options_load(void) +weechat_aspell_check_word (struct t_gui_buffer *buffer, const char *word) { - char *buffer; - int n; + char *clean_word; + struct t_aspell_speller *ptr_speller; + int rc; - buffer = weechat_aspell_plugin->get_plugin_config (weechat_aspell_plugin, "word-size"); - if (buffer) - { - aspell_plugin_options.word_size = atoi (buffer); - free (buffer); - } - else - aspell_plugin_options.word_size = _PLUGIN_OPTION_WORD_SIZE; + clean_word = weechat_aspell_string_strip_punctuation (word); - buffer = weechat_aspell_plugin->get_plugin_config (weechat_aspell_plugin, "check-sync"); - if (buffer) - { - aspell_plugin_options.check_sync = atoi (buffer); - if (aspell_plugin_options.check_sync != 0 && aspell_plugin_options.check_sync != 1) - aspell_plugin_options.check_sync = _PLUGIN_OPTION_CHECK_SYNC; - free (buffer); - } - else - aspell_plugin_options.check_sync = _PLUGIN_OPTION_CHECK_SYNC; + if (!clean_word) + return 1; + rc = 0; - buffer = weechat_aspell_plugin->get_plugin_config (weechat_aspell_plugin, "color"); - if (buffer) - { - n = weechat_aspell_plugin->get_irc_color (weechat_aspell_plugin, buffer); - if (n == -1) - { - aspell_plugin_options.color = weechat_aspell_plugin->get_irc_color (weechat_aspell_plugin, _PLUGIN_OPTION_COLOR); - aspell_plugin_options.color_name = strdup (_PLUGIN_OPTION_COLOR); - } - else - { - aspell_plugin_options.color = n; - aspell_plugin_options.color_name = strdup (buffer); - } - free (buffer); - } - else { - aspell_plugin_options.color = weechat_aspell_plugin->get_irc_color (weechat_aspell_plugin, _PLUGIN_OPTION_COLOR); - aspell_plugin_options.color_name = strdup (_PLUGIN_OPTION_COLOR); + /* word too small? then do not check word */ + if ((weechat_config_integer (weechat_aspell_config_check_word_min_length) > 0) + && ((int)strlen (clean_word) < weechat_config_integer (weechat_aspell_config_check_word_min_length))) + rc = 1; + else + { + /* word is URL? then do not check word */ + if (weechat_aspell_string_is_url (clean_word)) + rc = 1; + else + { + /* word is a number? then do not check word */ + if (weechat_aspell_string_is_simili_number (clean_word)) + rc = 1; + else + { + /* word is a nick of nicklist on this buffer? then do not check word */ + if (weechat_nicklist_search_nick (buffer, NULL, clean_word)) + rc = 1; + else + { + /* check word with all spellers for this buffer (order is important) */ + for (ptr_speller = weechat_aspell_spellers; ptr_speller; + ptr_speller = ptr_speller->next_speller) + { + if (aspell_speller_check (ptr_speller->speller, clean_word, -1) == 1) + { + rc = 1; + break; + } + } + } + } + } } - weechat_aspell_plugin->print_server (weechat_aspell_plugin, "[%s] [LOAD] options loaded", _PLUGIN_NAME); - return 1; + free (clean_word); + + return rc; } /* - * weechat_aspell_speller_command : manage "/aspell" uses + * weechat_aspell_modifier_cb: modifier for input text */ -int -weechat_aspell_speller_command (t_weechat_plugin *p, - int argc, char **argv, - char *handler_args, - void *handler_pointer) +char * +weechat_aspell_modifier_cb (void *data, const char *modifier, + const char *modifier_data, const char *string) { - char helpcmd[32]; - char **args; - int c, r; + struct t_gui_buffer *buffer; + unsigned int value; + char *result, *ptr_string, *pos_space, *color_normal, *color_error; + int length, index_result, length_word, word_ok; + int length_color_normal, length_color_error; /* make C compiler happy */ - (void) p; - (void) handler_args; - (void) handler_pointer; - - snprintf(helpcmd, sizeof(helpcmd), "/help %s", plugin_command); - r = 0; - - if ((argc == 3) && argv[1] && argv[2]) - { - args = weechat_aspell_plugin->explode_string (weechat_aspell_plugin, argv[2], " ", 0, &c); - if (args) - { - if (c >= 1) - { - if (strcmp (args[0], "dictlist") == 0) - { - weechat_aspell_speller_list_dicts (); - r = 1; - } - else if (strcmp (args[0], "show") == 0) - { - weechat_aspell_config_show (); - r = 1; - } - else if (strcmp (args[0], "save") == 0) - { - weechat_aspell_config_save (); - weechat_aspell_options_save(); - r = 1; - } - else if (strcmp (args[0], "dump") == 0) - { - weechat_aspell_config_dump (); - r = 1; - } - else if (strcmp (args[0], "enable") == 0) - { - if (c >= 2) - { - weechat_aspell_config_enable (args[1]); - r = 1; - } - } - else if (strcmp (args[0], "disable") == 0) - weechat_aspell_config_disable (); - else if (strcmp (args[0], "set") == 0) - { - if (c >= 2) - { - r = weechat_aspell_config_set (args[1], args[2]); - } - } - else if (strcmp (args[0], "add-word") == 0) - { - if (c >= 2) - { - weechat_aspell_config_addword (args[1]); - r = 1; - } - } - - } - weechat_aspell_plugin->free_exploded_string (weechat_aspell_plugin, args); - } - } - - if (r == 0) - weechat_aspell_plugin->exec_command (weechat_aspell_plugin, NULL, NULL, helpcmd); + (void) data; + (void) modifier; - return PLUGIN_RC_OK; -} - -/* - * weechat_aspell_nick_in_server_channel : - * check presence of a nick in a server/channel - */ - -int -weechat_aspell_nick_in_channel (char *nick, char *server, char *channel) -{ - t_plugin_nick_info *nick_info, *ptr_nick; - int ret; - - ret = 0; - if (!nick || !server || ! channel) - return ret; + if (!string) + return NULL; - nick_info = weechat_aspell_plugin->get_nick_info ( - weechat_aspell_plugin, server, channel); - if (!nick_info) - return ret; - - for(ptr_nick = nick_info; ptr_nick; ptr_nick = ptr_nick->next_nick) - { - if (strcmp (nick, ptr_nick->nick) == 0) { - ret = 1; - break; - } - } + sscanf (modifier_data, "%x", &value); + buffer = (struct t_gui_buffer *)value; - weechat_aspell_plugin->free_nick_info (weechat_aspell_plugin, nick_info); - - return ret; -} - -/* - * weechat_aspell_clean_word : - * strip punct chars at the begining and at the end of a word - */ - -char * -weechat_aspell_clean_word (char *word, int *offset) -{ - int len; - char *buffer, *w, *p; - - if (!word) - return NULL; + if (!weechat_aspell_spellers) + return NULL; - buffer = strdup (word); - - *offset = 0; - p = buffer; - while (p) + /* for performance: return last stirng built if input string is the + same (for example user just change cursor position, or input text is + refreshed with same content */ + if (aspell_last_modifier_string + && (strcmp (string, aspell_last_modifier_string) == 0)) { - if (!ispunct(*p)) - break; - p++; - (*offset)++; + return (aspell_last_modifier_result) ? + strdup (aspell_last_modifier_result) : NULL; } - - p = buffer + strlen(buffer) - 1; - while (p >= buffer) + + /* free last modifier string and result */ + if (aspell_last_modifier_string) { - if (!ispunct(*p)) - break; - p--; + free (aspell_last_modifier_string); + aspell_last_modifier_string = NULL; } - - len = p - buffer - *offset + 1; - if (len <= 0) + if (aspell_last_modifier_result) { - free (buffer); - return NULL; + free (aspell_last_modifier_result); + aspell_last_modifier_result = NULL; } - w = malloc (len+1); - - if (w) { - memcpy (w, buffer + *offset, len); - w[len] = '\0'; - } - - free (buffer); - - return w; -} - -/* - * weechat_aspell_is_simili_number : - * detect if a word is made of chars and punctation - */ - -int -weechat_aspell_is_simili_number (char *word) -{ - int len, ret, i; + /* save last modifier string received */ + aspell_last_modifier_string = strdup (string); - ret = 1; - len = strlen (word); + color_normal = weechat_color (weechat_config_string (weechat_config_get ("weechat.color.input"))); + length_color_normal = strlen (color_normal); + color_error = weechat_color (weechat_config_string (weechat_aspell_config_look_color)); + length_color_error = strlen (color_error); - if (!word) - return 0; + length = strlen (string); + result = malloc (length + (length * length_color_error)); + result[0] = '\0'; - for (i=0; iget_info (weechat_aspell_plugin, "channel", NULL); - server = weechat_aspell_plugin->get_info (weechat_aspell_plugin, "server", NULL); - - if (!server || !channel) - return PLUGIN_RC_OK; - - c = weechat_aspell_config_list_search (server, channel); - if (!c) - return PLUGIN_RC_OK; - - if (aspell_plugin_options.check_sync == 0 && argv[0] && argv[0][0]) - { - if (argv[0][0] == '*' && !ispunct (argv[0][1]) && !isspace (argv[0][1])) - return PLUGIN_RC_OK; - } - - if (!(argc == 3 && argv[1] && argv[2])) - return PLUGIN_RC_OK; - - if (strcmp (argv[1], argv[2]) == 0) - return PLUGIN_RC_OK; + (void) data; - input = weechat_aspell_plugin->get_info (weechat_aspell_plugin, "input", NULL); - if (!input) - return PLUGIN_RC_OK; - - if (!input[0]) - return PLUGIN_RC_OK; - - if (input[0] == '/') + if (argc > 1) { - keep_cmd_found = 0; - for(cmd = cmd_tokeep; cmd->cmd; ++cmd) - { - if (strncasecmp (input, cmd->cmd, cmd->len) == 0) { - keep_cmd_found = 1; - break; - } - } - if (keep_cmd_found == 0) - return PLUGIN_RC_OK; + if (weechat_strcasecmp (argv[1], "dictlist") == 0) + { + weechat_aspell_speller_list_dicts (); + return WEECHAT_RC_OK; + } + if (weechat_strcasecmp (argv[1], "addword") == 0) + { + if (argc > 3) + weechat_aspell_add_word (argv[2], argv_eol[3]); + else + { + if (!weechat_aspell_spellers) + { + weechat_printf (NULL, + _("%s%s: no dictionary on this buffer for " + "adding word"), + weechat_prefix ("error"), + ASPELL_PLUGIN_NAME); + } + else if (weechat_aspell_spellers->next_speller) + { + weechat_printf (NULL, + _("%s%s: many dictionaries are defined for " + "this buffer, please specify dictionary"), + weechat_prefix ("error"), + ASPELL_PLUGIN_NAME); + } + else + weechat_aspell_add_word (weechat_aspell_spellers->lang, + argv_eol[2]); + } + return WEECHAT_RC_OK; + } + if (weechat_strcasecmp (argv[1], "enable") == 0) + { + if (argc > 2) + { + dicts = weechat_string_replace (argv_eol[2], " ", ""); + weechat_aspell_set_dict (buffer, + (dicts) ? dicts : argv[2]); + if (dicts) + free (dicts); + } + return WEECHAT_RC_OK; + } + if (weechat_strcasecmp (argv[1], "disable") == 0) + { + weechat_aspell_set_dict (buffer, NULL); + return WEECHAT_RC_OK; + } } - count = 0; - ptr_input = input; - weechat_aspell_plugin->input_color (weechat_aspell_plugin, 0, 0, 0); - while (ptr_input && ptr_input[0]) - { - pos_space = strchr (ptr_input, ' '); - if (pos_space) - pos_space[0] = '\0'; - - if (ptr_input[0] != '/' && ptr_input[0] != '-' && ptr_input[0] != '#') - { - clword = weechat_aspell_clean_word (ptr_input, &offset); - if (clword) - { - if ( (int) strlen (clword) >= aspell_plugin_options.word_size) - { - if (!weechat_aspell_is_url (clword)) - { - if (!weechat_aspell_is_simili_number (clword)) - { - if (!weechat_aspell_nick_in_channel (clword, server, channel)) - { - if (aspell_speller_check (c->speller->speller, clword, -1) != 1) - { - if (count == 0) - weechat_aspell_plugin->input_color (weechat_aspell_plugin, 0, 0, 0); - weechat_aspell_plugin->input_color (weechat_aspell_plugin, aspell_plugin_options.color, - ptr_input - input + offset, strlen (clword)); - count++; - } - } - } - } - } - free (clword); - } - } - - if (pos_space) - { - pos_space[0] = ' '; - ptr_input = pos_space + 1; - while (ptr_input[0] == ' ') - ptr_input++; - } - else - ptr_input = NULL; - } - weechat_aspell_plugin->input_color (weechat_aspell_plugin, -1, 0, 0); - - free (input); - - return PLUGIN_RC_OK; + return WEECHAT_RC_OK; } /* - * weechat_plugin_init : init function, called when plugin is loaded + * weechat_plugin_init : init aspell plugin */ int -weechat_plugin_init (t_weechat_plugin *plugin) +weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) { - char help[1024]; - aspell_plugin_speller = NULL; - aspell_plugin_config = NULL; - weechat_aspell_plugin = plugin; - - snprintf (help, sizeof(help), - " show : show plugin configuration\n" - "dictlist : show installed dictionnaries\n" - " save : save plugin configuration\n" - " enable : enable aspell on current channel/server\n" - " disable : disable aspell on current channel/server\n" - "add-word : add a word in your personnal aspell dict\n" - " dump : show plugins internals (usefull for debug)\n" - " set : setting options\n" - " OPTION := { word-size SIZE | toogle-check-mode | color COLOR }\n" - " word-size : minimum size for a word to be checked (default : %d)\n" - " toggle-check-mode : switch between a realtime or an asynchronous checking\n" - " color : color of the mispelled words\n" - "\n" - " *NB : input line beginning with a '/' is not checked\n", - _PLUGIN_OPTION_WORD_SIZE); - - weechat_aspell_plugin->cmd_handler_add (weechat_aspell_plugin, "aspell", - "Aspell Plugin configuration", - "{ show | save | dictlist | set [OPTION [VALUE]] | add-word WORD | enable LANG | disable | dump }", - help, - "show|dictlist|save|enable|disable|set|add-word|dump word-size|toggle-check-mode|color", - &weechat_aspell_speller_command, NULL, NULL); - - weechat_aspell_plugin->keyboard_handler_add ( - weechat_aspell_plugin, &weechat_aspell_keyb_check, NULL, NULL); - - weechat_aspell_options_load (); - weechat_aspell_config_load (); - - return PLUGIN_RC_OK; + /* make C compiler happy */ + (void) argc; + (void) argv; + + weechat_plugin = plugin; + + if (!weechat_aspell_config_init ()) + return WEECHAT_RC_ERROR; + + if (weechat_aspell_config_read () < 0) + return WEECHAT_RC_ERROR; + + /* callback for debug */ + weechat_hook_signal ("debug", &weechat_aspell_debug_cb, NULL); + + /* command /aspell */ + weechat_hook_command ("aspell", + N_("aspell plugin configuration"), + N_("[list | enable lang | disable | addword [lang] " + "word]"), + N_(" list: show installed dictionnaries\n" + " enable: enable aspell on current buffer\n" + "disable: disable aspell on current buffer\n" + "addword: add a word in your personnal aspell dictionary\n" + "\n" + "Input line beginning with a '/' is not checked, " + "except for some commands."), + "list|enable|disable|addword", + &weechat_aspell_command_cb, NULL); + + /* callback for buffer_switch */ + weechat_hook_signal ("buffer_switch", + &weechat_aspell_buffer_switch_cb, NULL); + + /* callback for spell checking input text */ + weechat_hook_modifier ("weechat_input_text_display", + &weechat_aspell_modifier_cb, NULL); + + weechat_aspell_create_spellers (weechat_current_buffer); + + return WEECHAT_RC_OK; } /* - * weechat_plugin_end : end function, called when plugin is unloaded + * weechat_plugin_end : end aspell plugin */ -void -weechat_plugin_end (t_weechat_plugin *p) +int +weechat_plugin_end (struct t_weechat_plugin *plugin) { - aspell_speller_t *s, *t; - aspell_config_t *c, *d; - /* make C compiler happy */ - (void) p; + (void) plugin; - weechat_aspell_options_save (); - weechat_aspell_config_save (); - - /* freeing memory */ + weechat_aspell_config_write (); - /* options */ - if (aspell_plugin_options.color_name) - free (aspell_plugin_options.color_name); - - /* spellers */ - s = aspell_plugin_speller; - while ( s != NULL) - { - t = s; - s = s->next_speller; - weechat_aspell_free_speller (t); - } + weechat_aspell_speller_free_all (); - /* config */ - c = aspell_plugin_config; - while ( c != NULL) - { - d = c; - c = c->next_config; - weechat_aspell_free_config (c); - } + if (aspell_last_modifier_string) + free (aspell_last_modifier_string); + if (aspell_last_modifier_result) + free (aspell_last_modifier_result); + + weechat_aspell_config_free (); + + return WEECHAT_RC_OK; } diff --git a/src/plugins/aspell/aspell.h b/src/plugins/aspell/aspell.h index 71d528960..42dc2217b 100644 --- a/src/plugins/aspell/aspell.h +++ b/src/plugins/aspell/aspell.h @@ -16,180 +16,28 @@ * along with this program. If not, see . */ -/* weechat-aspell.h: Aspell plugin support for WeeChat */ #ifndef __WEECHAT_ASPELL_H #define __WEECHAT_ASPELL_H 1 #include -#define _PLUGIN_OPTION_WORD_SIZE 2 -#define _PLUGIN_OPTION_CHECK_SYNC 0 -#define _PLUGIN_OPTION_COLOR "red" +#define weechat_plugin weechat_aspell_plugin +#define ASPELL_PLUGIN_NAME "aspell" -typedef struct aspell_speller_t -{ - AspellSpeller *speller; - char *lang; - int refs; - - struct aspell_speller_t *prev_speller; - struct aspell_speller_t *next_speller; -} aspell_speller_t; - -typedef struct aspell_config_t -{ - char *server; - char *channel; - aspell_speller_t *speller; - - struct aspell_config_t *prev_config; - struct aspell_config_t *next_config; -} aspell_config_t; - -typedef struct aspell_options_t -{ - int word_size; - int check_sync; - int color; - char *color_name; -} aspell_options_t; - -typedef struct iso_langs_t +struct t_aspell_code { char *code; char *name; -} iso_langs_t; - -typedef struct iso_countries_t -{ - char *code; - char *name; -} iso_countries_t; +}; -typedef struct cmds_keep_t -{ - char *cmd; - int len; -} cmds_keep_t; +extern int aspell_debug; -/* aspell supported langs 2006-05-27 */ -iso_langs_t langs_avail[] = -{ - { "af", "Afrikaans"}, - { "am", "Amharic"}, - { "az", "Azerbaijani"}, - { "be", "Belarusian"}, - { "bg", "Bulgarian"}, - { "bn", "Bengali"}, - { "br", "Breton"}, - { "ca", "Catalan"}, - { "cs", "Czech"}, - { "csb", "Kashubian"}, - { "cy", "Welsh"}, - { "da", "Danish"}, - { "de", "German"}, - { "el", "Greek Modern"}, - { "en", "English"}, - { "eo", "Esperanto"}, - { "es", "Spanish"}, - { "et", "Estonian"}, - { "fa", "Persian"}, - { "fi", "Finnish"}, - { "fo", "Faroese"}, - { "fr", "French"}, - { "ga", "Irish"}, - { "gd", "Gaelic"}, - { "gl", "Galician"}, - { "gu", "Gujarati"}, - { "gv", "Manx"}, - { "he", "Hebrew"}, - { "hi", "Hiligaynon"}, - { "hr", "Croatian"}, - { "hsb", "Upper Sorbian"}, - { "hu", "Hungarian"}, - { "ia", "Interlingua"}, - { "id", "Indonesian"}, - { "is", "Icelandic"}, - { "it", "Italian"}, - { "ku", "Kurdish"}, - { "la", "Latin"}, - { "lt", "Lithuanian"}, - { "lv", "Latvian"}, - { "mg", "Malagasy"}, - { "mi", "Maori"}, - { "mk", "Macedonian"}, - { "mn", "Mongolian"}, - { "mr", "Marathi"}, - { "ms", "Malay"}, - { "mt", "Maltese"}, - { "nb", "Norwegian Bokmal"}, - { "nds", "Saxon Low"}, - { "nl", "Flemish"}, - { "nn", "Norwegian Nynorsk"}, - { "no", "Norwegian"}, - { "ny", "Nyanja"}, - { "or", "Oriya"}, - { "pa", "Panjabi"}, - { "pl", "Polish"}, - { "pt", "Portuguese"}, - { "qu", "Quechua"}, - { "ro", "Romanian"}, - { "ru", "Russian"}, - { "rw", "Kinyarwanda"}, - { "sc", "Sardinian"}, - { "sk", "Slovak"}, - { "sl", "Slovenian"}, - { "sr", "Serbian"}, - { "sv", "Swedish"}, - { "sw", "Swahili"}, - { "ta", "Tamil"}, - { "te", "Telugu"}, - { "tet", "Tetum"}, - { "tl", "Tagalog"}, - { "tn", "Tswana"}, - { "tr", "Turkish"}, - { "uk", "Ukrainian"}, - { "uz", "Uzbek"}, - { "vi", "Vietnamese"}, - { "wa", "Walloon"}, - { "yi", "Yiddish"}, - { "zu", "Zulu"}, - { NULL, NULL} -}; +extern struct t_weechat_plugin *weechat_aspell_plugin; -iso_countries_t countries_avail[] = -{ - { "AT", "Austria" }, - { "BR", "Brazil" }, - { "CA", "Canada" }, - { "CH", "Switzerland" }, - { "DE", "Germany" }, - { "FR", "France" }, - { "GB", "Great Britain" }, - { "PT", "Portugal" }, - { "SK", "Slovakia" }, - { "US", "United States of America" }, - { NULL, NULL} -}; +extern struct t_aspell_code langs_avail[]; +extern struct t_aspell_code countries_avail[]; -/* internal or irc commands to be use with spellchecking */ -cmds_keep_t cmd_tokeep[] = -{ - { "/builtin ", 9 }, - { "/ame " , 5 }, - { "/amsg " , 6 }, - { "/away " , 6 }, - { "/cycle " , 7 }, - { "/kick " , 6 }, - { "/kickban " , 9 }, - { "/me " , 4 }, - { "/notice " , 8 }, - { "/part " , 6 }, - { "/query " , 7 }, - { "/quit " , 6 }, - { "/topic " , 7 }, - { NULL, 0} -}; +extern void weechat_aspell_create_spellers (struct t_gui_buffer *buffer); #endif /* aspell.h */ diff --git a/src/plugins/charset/charset.c b/src/plugins/charset/charset.c index b76d1dc5e..d124d6d10 100644 --- a/src/plugins/charset/charset.c +++ b/src/plugins/charset/charset.c @@ -354,7 +354,7 @@ charset_decode_cb (void *data, const char *modifier, const char *modifier_data, { weechat_printf (NULL, "charset: debug: using 'decode' charset: %s " - "(modifier='%s', modifier_data='%s', string='%s')", + "(modifier=\"%s\", modifier_data=\"%s\", string=\"%s\")", charset, modifier, modifier_data, string); } if (charset && charset[0]) @@ -383,7 +383,7 @@ charset_encode_cb (void *data, const char *modifier, const char *modifier_data, { weechat_printf (NULL, "charset: debug: using 'encode' charset: %s " - "(modifier='%s', modifier_data='%s', string='%s')", + "(modifier=\"%s\", modifier_data=\"%s\", string=\"%s\")", charset, modifier, modifier_data, string); } if (charset && charset[0]) @@ -407,11 +407,11 @@ charset_set (struct t_config_section *section, const char *type, value) > 0) { if (value && value[0]) - weechat_printf (NULL, _("Charset: %s, %s => %s"), - type, name, value); + weechat_printf (NULL, "%s: %s, %s => %s", + CHARSET_PLUGIN_NAME, type, name, value); else - weechat_printf (NULL, _("Charset: %s, %s: removed"), - type, name); + weechat_printf (NULL, _("%s: %s, %s: removed"), + CHARSET_PLUGIN_NAME, type, name); } } diff --git a/src/plugins/demo/demo.c b/src/plugins/demo/demo.c index 08c4dc5fd..bedb096f9 100644 --- a/src/plugins/demo/demo.c +++ b/src/plugins/demo/demo.c @@ -87,7 +87,7 @@ demo_printf_command_cb (void *data, struct t_gui_buffer *buffer, int argc, if (argc > 1) weechat_printf (buffer, - "demo_printf: '%s'", argv_eol[1]); + "demo_printf: \"%s\"", argv_eol[1]); else { weechat_printf (buffer, @@ -121,7 +121,7 @@ demo_buffer_input_data_cb (void *data, struct t_gui_buffer *buffer, weechat_printf (buffer, "buffer_input_data_cb: buffer = %x (%s), " - "input_data = '%s'", + "input_data = \"%s\"", buffer, weechat_buffer_get_string (buffer, "name"), input_data); @@ -372,7 +372,7 @@ demo_signal_cb (void *data, const char *signal, const char *type_data, { weechat_printf (NULL, _("demo_signal: signal: %s, type_data: %s, " - "signal_data: '%s'"), + "signal_data: \"%s\""), signal, type_data, (char *)signal_data); } else if (strcmp (type_data, WEECHAT_HOOK_SIGNAL_INT) == 0) diff --git a/src/plugins/irc/irc-command.c b/src/plugins/irc/irc-command.c index 7d6d7b987..e89865ed1 100644 --- a/src/plugins/irc/irc-command.c +++ b/src/plugins/irc/irc-command.c @@ -2795,7 +2795,7 @@ irc_command_server (void *data, struct t_gui_buffer *buffer, int argc, { weechat_printf (NULL, ""); weechat_printf (NULL, - _("Servers with '%s':"), + _("Servers with \"%s\":"), server_name); } one_server_found = 1; diff --git a/src/plugins/irc/irc-ignore.c b/src/plugins/irc/irc-ignore.c index 22d827436..d69b05edf 100644 --- a/src/plugins/irc/irc-ignore.c +++ b/src/plugins/irc/irc-ignore.c @@ -230,9 +230,9 @@ irc_ignore_free (struct t_irc_ignore *ignore) /* remove filter from filters list */ if (ignore->prev_ignore) - ignore->prev_ignore->next_ignore = ignore->next_ignore; + (ignore->prev_ignore)->next_ignore = ignore->next_ignore; if (ignore->next_ignore) - ignore->next_ignore->prev_ignore = ignore->prev_ignore; + (ignore->next_ignore)->prev_ignore = ignore->prev_ignore; if (irc_ignore_list == ignore) irc_ignore_list = ignore->next_ignore; if (last_irc_ignore == ignore) diff --git a/src/plugins/logger/logger-config.h b/src/plugins/logger/logger-config.h index e789e7f7a..c2c1d6fa1 100644 --- a/src/plugins/logger/logger-config.h +++ b/src/plugins/logger/logger-config.h @@ -23,8 +23,6 @@ #define LOGGER_CONFIG_NAME "logger" -extern struct t_config_file *logger_config_file; - extern struct t_config_option *logger_config_look_backlog; extern struct t_config_option *logger_config_file_auto_log; diff --git a/src/plugins/scripts/script.c b/src/plugins/scripts/script.c index 71211a702..7a880d97a 100644 --- a/src/plugins/scripts/script.c +++ b/src/plugins/scripts/script.c @@ -179,7 +179,7 @@ script_ptr2str (void *pointer) if (!pointer) return strdup (""); - snprintf (pointer_str, sizeof (pointer_str) - 1, + snprintf (pointer_str, sizeof (pointer_str), "0x%x", (unsigned int)pointer); return strdup (pointer_str); -- cgit v1.2.3