1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-29 14:26:39 +02:00

aspell: add bar item "aspell_suggest": suggestions for misspelled word at cursor (task #12061) (patch from Nils Görs)

This commit is contained in:
Sebastien Helleu
2012-11-04 11:50:15 +01:00
parent 9e94bfd48b
commit 57d5afeda5
27 changed files with 462 additions and 57 deletions
+42 -1
View File
@@ -50,13 +50,53 @@ weechat_aspell_bar_item_dict (void *data, struct t_gui_bar_item *item,
window = weechat_current_window ();
buffer = weechat_window_get_pointer (window, "buffer");
if (buffer)
{
dict_list = weechat_aspell_get_dict (buffer);
if (dict_list)
return strdup (dict_list);
}
return NULL;
}
/*
* weechat_aspell_bar_item_suggest: bar item with aspell suggestions
*/
char *
weechat_aspell_bar_item_suggest (void *data, struct t_gui_bar_item *item,
struct t_gui_window *window)
{
struct t_gui_buffer *buffer;
const char *suggestions;
char str_delim[128], *suggestions2;
/* make C compiler happy */
(void) data;
(void) item;
if (!window)
window = weechat_current_window ();
buffer = weechat_window_get_pointer (window, "buffer");
if (buffer)
{
suggestions = weechat_buffer_get_string (buffer,
"localvar_aspell_suggest");
if (suggestions)
{
snprintf (str_delim, sizeof (str_delim),
"%s/%s",
weechat_color ("bar_delim"),
weechat_color ("bar_fg"));
suggestions2 = weechat_string_replace (suggestions, "/", str_delim);
if (suggestions2)
return suggestions2;
return strdup (suggestions);
}
}
return NULL;
}
@@ -68,4 +108,5 @@ void
weechat_aspell_bar_item_init ()
{
weechat_bar_item_new ("aspell_dict", &weechat_aspell_bar_item_dict, NULL);
weechat_bar_item_new ("aspell_suggest", &weechat_aspell_bar_item_suggest, NULL);
}
@@ -46,6 +46,7 @@ struct t_config_option *weechat_aspell_config_check_default_dict;
struct t_config_option *weechat_aspell_config_check_during_search;
struct t_config_option *weechat_aspell_config_check_enabled;
struct t_config_option *weechat_aspell_config_check_real_time;
struct t_config_option *weechat_aspell_config_check_suggestions;
struct t_config_option *weechat_aspell_config_check_word_min_length;
@@ -132,6 +133,22 @@ weechat_aspell_config_change_enabled (void *data, struct t_config_option *option
weechat_bar_item_update ("input_text");
}
/*
* weechat_aspell_config_change_suggestions: called when number of suggestions
* is changed
*/
void
weechat_aspell_config_change_suggestions (void *data,
struct t_config_option *option)
{
/* make C compiler happy */
(void) data;
(void) option;
weechat_bar_item_update ("aspell_suggest");
}
/*
* weechat_aspell_config_dict_change: called when a dictionary is changed
*/
@@ -452,6 +469,14 @@ weechat_aspell_config_init ()
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, 0, NULL, NULL, NULL, NULL, NULL, NULL);
weechat_aspell_config_check_suggestions = weechat_config_new_option (
weechat_aspell_config_file, ptr_section,
"suggestions", "integer",
N_("number of suggestions to display in bar item \"aspell_suggest\" "
"for each dictionary set in buffer (-1 = disable suggestions, "
"0 = display all possible suggestions in all languages)"),
NULL, -1, INT_MAX, "-1", NULL, 0,
NULL, NULL, &weechat_aspell_config_change_suggestions, NULL, NULL, NULL);
weechat_aspell_config_check_word_min_length = weechat_config_new_option (
weechat_aspell_config_file, ptr_section,
"word_min_length", "integer",
@@ -31,6 +31,7 @@ extern struct t_config_option *weechat_aspell_config_check_default_dict;
extern struct t_config_option *weechat_aspell_config_check_during_search;
extern struct t_config_option *weechat_aspell_config_check_enabled;
extern struct t_config_option *weechat_aspell_config_check_real_time;
extern struct t_config_option *weechat_aspell_config_check_suggestions;
extern struct t_config_option *weechat_aspell_config_check_word_min_length;
extern char **weechat_aspell_commands_to_check;
+4 -4
View File
@@ -44,7 +44,7 @@ weechat_aspell_speller_exists (const char *lang)
{
struct AspellConfig *config;
AspellDictInfoList *list;
AspellDictInfoEnumeration *el;
AspellDictInfoEnumeration *elements;
const AspellDictInfo *dict;
int rc;
@@ -52,9 +52,9 @@ weechat_aspell_speller_exists (const char *lang)
config = new_aspell_config ();
list = get_aspell_dict_info_list (config);
el = aspell_dict_info_list_elements (list);
elements = aspell_dict_info_list_elements (list);
while ((dict = aspell_dict_info_enumeration_next (el)))
while ((dict = aspell_dict_info_enumeration_next (elements)) != NULL)
{
if (strcmp (dict->name, lang) == 0)
{
@@ -63,7 +63,7 @@ weechat_aspell_speller_exists (const char *lang)
}
}
delete_aspell_dict_info_enumeration (el);
delete_aspell_dict_info_enumeration (elements);
delete_aspell_config (config);
return rc;
+150 -14
View File
@@ -49,6 +49,7 @@ int aspell_enabled = 0;
struct t_gui_buffer *aspell_buffer_spellers = NULL;
char *aspell_last_modifier_string = NULL; /* last str. received by modifier */
int aspell_last_buffer_input_pos = -1; /* last cursor position */
char *aspell_last_modifier_result = NULL; /* last str. built by modifier */
/*
@@ -385,7 +386,6 @@ weechat_aspell_iso_to_lang (const char *code)
return strdup ("Unknown");
}
/*
* weechat_aspell_iso_to_country: convert an aspell iso country code in its
* english full name
@@ -418,12 +418,12 @@ weechat_aspell_speller_list_dicts ()
char buffer[192];
struct AspellConfig *config;
AspellDictInfoList *list;
AspellDictInfoEnumeration *el;
AspellDictInfoEnumeration *elements;
const AspellDictInfo *dict;
config = new_aspell_config();
list = get_aspell_dict_info_list (config);
el = aspell_dict_info_list_elements (list);
elements = aspell_dict_info_list_elements (list);
weechat_printf (NULL, "");
weechat_printf (NULL,
@@ -431,7 +431,7 @@ weechat_aspell_speller_list_dicts ()
_( "%s dictionaries list:"),
ASPELL_PLUGIN_NAME);
while ((dict = aspell_dict_info_enumeration_next (el)))
while ((dict = aspell_dict_info_enumeration_next (elements)) != NULL)
{
country = NULL;
pos = strchr (dict->code, '_');
@@ -481,7 +481,7 @@ weechat_aspell_speller_list_dicts ()
free (country);
}
delete_aspell_dict_info_enumeration (el);
delete_aspell_dict_info_enumeration (elements);
delete_aspell_config (config);
}
@@ -617,7 +617,6 @@ weechat_aspell_check_word (struct t_gui_buffer *buffer, const char *word)
{
struct t_aspell_speller *ptr_speller;
int rc;
rc = 0;
/* word too small? then do not check word */
@@ -653,6 +652,74 @@ weechat_aspell_check_word (struct t_gui_buffer *buffer, const char *word)
return rc;
}
/*
* weechat_aspell_get_suggestions: get suggestions for a word
* A string is returned with format:
* "suggest1,suggest2,suggest3"
* Note: result (if not NULL) must be free()
* after use.
*/
char *
weechat_aspell_get_suggestions (const char *word)
{
struct t_aspell_speller *ptr_speller;
int size, max_suggestions, num_suggestions;
char *suggestions, *suggestions2;
const char *ptr_word;
const AspellWordList *list;
AspellStringEnumeration *elements;
max_suggestions = weechat_config_integer (weechat_aspell_config_check_suggestions);
if (max_suggestions < 0)
return NULL;
size = 1;
suggestions = malloc (size);
if (!suggestions)
return NULL;
suggestions[0] = '\0';
for (ptr_speller = weechat_aspell_spellers; ptr_speller;
ptr_speller = ptr_speller->next_speller)
{
list = aspell_speller_suggest (ptr_speller->speller, word, -1);
if (list)
{
elements = aspell_word_list_elements (list);
num_suggestions = 0;
while ((ptr_word = aspell_string_enumeration_next (elements)) != NULL)
{
size += strlen (ptr_word) + ((suggestions[0]) ? 1 : 0);
suggestions2 = realloc (suggestions, size);
if (!suggestions2)
{
free (suggestions);
delete_aspell_string_enumeration (elements);
return NULL;
}
suggestions = suggestions2;
if (suggestions[0])
strcat (suggestions, (num_suggestions == 0) ? "/" : ",");
strcat (suggestions, ptr_word);
num_suggestions++;
if ((max_suggestions >= 0) && (num_suggestions == max_suggestions))
break;
}
delete_aspell_string_enumeration (elements);
}
}
/* no suggestions found */
if (!suggestions[0])
{
free (suggestions);
return NULL;
}
return suggestions;
}
/*
* weechat_aspell_modifier_cb: modifier for input text
*/
@@ -664,10 +731,12 @@ weechat_aspell_modifier_cb (void *data, const char *modifier,
long unsigned int value;
struct t_gui_buffer *buffer;
char *result, *ptr_string, *pos_space, *ptr_end, save_end;
const char *color_normal, *color_error;
char *word_for_suggestions, *old_suggestions, *suggestions;
const char *color_normal, *color_error, *ptr_suggestions;
int buffer_has_changed, utf8_char_int, char_size;
int length, index_result, length_word, word_ok;
int length_color_normal, length_color_error, rc;
int input_pos, current_pos, word_start_pos, word_end_pos;
/* make C compiler happy */
(void) data;
@@ -676,7 +745,7 @@ weechat_aspell_modifier_cb (void *data, const char *modifier,
if (!aspell_enabled)
return NULL;
if (!string || !string[0])
if (!string)
return NULL;
rc = sscanf (modifier_data, "%lx", &value);
@@ -703,12 +772,14 @@ weechat_aspell_modifier_cb (void *data, const char *modifier,
/*
* for performance: return last string built if input string is the
* same (for example user just change cursor position, or input text is
* refreshed with same content)
* same and cursor position is the same (only if suggestions are enabled)
*/
input_pos = weechat_buffer_get_integer (buffer, "input_pos");
if (!buffer_has_changed
&& aspell_last_modifier_string
&& (strcmp (string, aspell_last_modifier_string) == 0))
&& (strcmp (string, aspell_last_modifier_string) == 0)
&& ((weechat_config_integer (weechat_aspell_config_check_suggestions) < 0)
|| (input_pos == aspell_last_buffer_input_pos)))
{
return (aspell_last_modifier_result) ?
strdup (aspell_last_modifier_result) : NULL;
@@ -726,8 +797,11 @@ weechat_aspell_modifier_cb (void *data, const char *modifier,
aspell_last_modifier_result = NULL;
}
word_for_suggestions = NULL;
/* save last modifier string received */
aspell_last_modifier_string = strdup (string);
aspell_last_buffer_input_pos = input_pos;
color_normal = weechat_color ("bar_fg");
length_color_normal = strlen (color_normal);
@@ -777,6 +851,7 @@ weechat_aspell_modifier_cb (void *data, const char *modifier,
ptr_string = pos_space;
}
current_pos = 0;
while (ptr_string[0])
{
/* find start of word */
@@ -789,6 +864,7 @@ weechat_aspell_modifier_cb (void *data, const char *modifier,
memcpy (result + index_result, ptr_string, char_size);
index_result += char_size;
ptr_string += char_size;
current_pos++;
if (!ptr_string[0])
break;
utf8_char_int = weechat_utf8_char_int (ptr_string);
@@ -796,12 +872,17 @@ weechat_aspell_modifier_cb (void *data, const char *modifier,
if (!ptr_string[0])
break;
word_start_pos = current_pos;
word_end_pos = current_pos;
/* find end of word */
ptr_end = weechat_utf8_next_char (ptr_string);
utf8_char_int = weechat_utf8_char_int (ptr_end);
while (iswalnum (utf8_char_int) || (utf8_char_int == '\'')
|| (utf8_char_int == '-'))
{
ptr_end = weechat_utf8_next_char (ptr_end);
word_end_pos++;
if (!ptr_end[0])
break;
utf8_char_int = weechat_utf8_char_int (ptr_end);
@@ -834,7 +915,20 @@ weechat_aspell_modifier_cb (void *data, const char *modifier,
{
if ((save_end != '\0')
|| (weechat_config_integer (weechat_aspell_config_check_real_time)))
{
word_ok = weechat_aspell_check_word (buffer, ptr_string);
if (!word_ok && (input_pos >= word_start_pos))
{
/*
* if word is misspelled and that cursor is after
* the beginning of this word, save the word (we will
* look for suggestions after this loop)
*/
if (word_for_suggestions)
free (word_for_suggestions);
word_for_suggestions = strdup (ptr_string);
}
}
else
word_ok = 1;
}
@@ -862,15 +956,55 @@ weechat_aspell_modifier_cb (void *data, const char *modifier,
ptr_end[0] = save_end;
ptr_string = ptr_end;
current_pos = word_end_pos + 1;
}
result[index_result] = '\0';
}
/* save old suggestions in buffer */
ptr_suggestions = weechat_buffer_get_string (buffer,
"localvar_aspell_suggest");
old_suggestions = (ptr_suggestions) ? strdup (ptr_suggestions) : NULL;
/* if there is a misspelled word, get suggestions and set them in buffer */
if (word_for_suggestions)
{
suggestions = weechat_aspell_get_suggestions (word_for_suggestions);
if (suggestions)
{
weechat_buffer_set (buffer, "localvar_set_aspell_suggest",
suggestions);
free (suggestions);
}
else
{
weechat_buffer_set (buffer, "localvar_del_aspell_suggest", "");
}
free (word_for_suggestions);
}
else
{
weechat_buffer_set (buffer, "localvar_del_aspell_suggest", "");
}
/* if suggestions have changed, update the bar item */
ptr_suggestions = weechat_buffer_get_string (buffer,
"localvar_aspell_suggest");
if ((old_suggestions && !ptr_suggestions)
|| (!old_suggestions && ptr_suggestions)
|| (old_suggestions && ptr_suggestions
&& (strcmp (old_suggestions, ptr_suggestions) != 0)))
{
weechat_bar_item_update ("aspell_suggest");
}
if (old_suggestions)
free (old_suggestions);
if (!result)
return NULL;
aspell_last_modifier_result = strdup (result);
return result;
}
@@ -1053,8 +1187,9 @@ weechat_aspell_buffer_switch_cb (void *data, const char *signal,
(void) type_data;
(void) signal_data;
/* refresh bar item "aspell_dict" (for root bars) */
/* refresh bar items (for root bars) */
weechat_bar_item_update ("aspell_dict");
weechat_bar_item_update ("aspell_suggest");
return WEECHAT_RC_OK;
}
@@ -1073,8 +1208,9 @@ weechat_aspell_window_switch_cb (void *data, const char *signal,
(void) type_data;
(void) signal_data;
/* refresh bar item "aspell_dict" (for root bars) */
/* refresh bar items (for root bars) */
weechat_bar_item_update ("aspell_dict");
weechat_bar_item_update ("aspell_suggest");
return WEECHAT_RC_OK;
}