comparison mcabber/src/screen.c @ 1179:0f7e0346d9cb

Add aspell support [Note: Patch slightly modified by Mikael]
author entragian <entragian@o2.pl>
date Wed, 04 Apr 2007 23:23:37 +0200
parents 220e04816524
children 5c34af370b67
comparison
equal deleted inserted replaced
1178:220e04816524 1179:0f7e0346d9cb
27 #include <ctype.h> 27 #include <ctype.h>
28 #include <locale.h> 28 #include <locale.h>
29 #include <langinfo.h> 29 #include <langinfo.h>
30 #include <config.h> 30 #include <config.h>
31 31
32 #ifdef HAVE_ASPELL_H
33 # include <aspell.h>
34 #endif
35
32 #include "screen.h" 36 #include "screen.h"
33 #include "utf8.h" 37 #include "utf8.h"
34 #include "hbuf.h" 38 #include "hbuf.h"
35 #include "commands.h" 39 #include "commands.h"
36 #include "compl.h" 40 #include "compl.h"
53 static inline void check_offset(int); 57 static inline void check_offset(int);
54 static void scr_cancel_current_completion(void); 58 static void scr_cancel_current_completion(void);
55 static void scr_end_current_completion(void); 59 static void scr_end_current_completion(void);
56 static void scr_insert_text(const char*); 60 static void scr_insert_text(const char*);
57 static void scr_handle_tab(void); 61 static void scr_handle_tab(void);
62
63 #ifdef HAVE_ASPELL_H
64 static void spellcheck(char *, char *);
65 static inline int is_alpha(const char *);
66 #endif
58 67
59 static GHashTable *winbufhash; 68 static GHashTable *winbufhash;
60 69
61 typedef struct { 70 typedef struct {
62 GList *hbuf; 71 GList *hbuf;
98 static bool log_win_on_top; 107 static bool log_win_on_top;
99 static bool roster_win_on_right; 108 static bool roster_win_on_right;
100 static time_t LastActivity; 109 static time_t LastActivity;
101 110
102 static char inputLine[INPUTLINE_LENGTH+1]; 111 static char inputLine[INPUTLINE_LENGTH+1];
112 #ifdef HAVE_ASPELL_H
113 static char maskLine[INPUTLINE_LENGTH+1];
114 #endif
103 static char *ptr_inputline; 115 static char *ptr_inputline;
104 static short int inputline_offset; 116 static short int inputline_offset;
105 static int completion_started; 117 static int completion_started;
106 static GList *cmdhisto; 118 static GList *cmdhisto;
107 static GList *cmdhisto_cur; 119 static GList *cmdhisto_cur;
125 static void add_keyseq(char *seqstr, guint mkeycode, gint value); 137 static void add_keyseq(char *seqstr, guint mkeycode, gint value);
126 138
127 void scr_WriteInWindow(const char *winId, const char *text, time_t timestamp, 139 void scr_WriteInWindow(const char *winId, const char *text, time_t timestamp,
128 unsigned int prefix_flags, int force_show); 140 unsigned int prefix_flags, int force_show);
129 141
142 #ifdef HAVE_ASPELL_H
143 #define ASPELLBADCHAR 5
144 AspellConfig *spell_config;
145 AspellSpeller *spell_checker;
146 #endif
130 147
131 /* Functions */ 148 /* Functions */
132 149
133 static int FindColor(const char *name) 150 static int FindColor(const char *name)
134 { 151 {
2808 } 2825 }
2809 } 2826 }
2810 inputline_offset = c - inputLine; 2827 inputline_offset = c - inputLine;
2811 } 2828 }
2812 2829
2830 #ifdef HAVE_ASPELL_H
2831 // prints inputLine with underlined words when misspelled
2832 static inline void print_checked_line(void)
2833 {
2834 char *wprint_char_fmt = "%c";
2835 int point;
2836 char *ptrCur = inputLine + inputline_offset;
2837
2838 #ifdef UNICODE
2839 // We need this to display a single UTF-8 char... Any better solution?
2840 if (utf8_mode)
2841 wprint_char_fmt = "%lc";
2842 #endif
2843
2844 wmove(inputWnd, 0, 0); // problem with backspace
2845
2846 while (*ptrCur) {
2847 point = ptrCur - inputLine;
2848 if (maskLine[point])
2849 wattrset(inputWnd, A_UNDERLINE);
2850 wprintw(inputWnd, wprint_char_fmt, get_char(ptrCur));
2851 wattrset(inputWnd, A_NORMAL);
2852 ptrCur = next_char(ptrCur);
2853 }
2854 }
2855 #endif
2856
2813 static inline void refresh_inputline(void) 2857 static inline void refresh_inputline(void)
2814 { 2858 {
2815 mvwprintw(inputWnd, 0,0, "%s", inputLine + inputline_offset); 2859 #ifdef HAVE_ASPELL_H
2860 if (settings_opt_get_int("aspell_enable")) {
2861 memset(maskLine, 0, INPUTLINE_LENGTH+1);
2862 spellcheck(inputLine, maskLine);
2863 }
2864 print_checked_line();
2816 wclrtoeol(inputWnd); 2865 wclrtoeol(inputWnd);
2817 if (*ptr_inputline) { 2866 if (*ptr_inputline) {
2818 // hack to set cursor pos. Characters can have different width, 2867 // hack to set cursor pos. Characters can have different width,
2819 // so I know of no better way. 2868 // so I know of no better way.
2820 char c = *ptr_inputline; 2869 char c = *ptr_inputline;
2821 *ptr_inputline = 0; 2870 *ptr_inputline = 0;
2822 mvwprintw(inputWnd, 0,0, "%s", inputLine + inputline_offset); 2871 print_checked_line();
2823 *ptr_inputline = c; 2872 *ptr_inputline = c;
2824 } 2873 }
2874 #else
2875 mvwprintw(inputWnd, 0, 0, "%s", inputLine + inputline_offset);
2876 wclrtoeol(inputWnd);
2877 if (*ptr_inputline) {
2878 // hack to set cursor pos. Characters can have different width,
2879 // so I know of no better way.
2880 char c = *ptr_inputline;
2881 *ptr_inputline = 0;
2882 mvwprintw(inputWnd, 0, 0, "%s", inputLine + inputline_offset);
2883 *ptr_inputline = c;
2884 }
2885 #endif
2825 } 2886 }
2826 2887
2827 void scr_handle_CtrlC(void) 2888 void scr_handle_CtrlC(void)
2828 { 2889 {
2829 if (!Curses) return; 2890 if (!Curses) return;
3132 time(&chatstate_timestamp); 3193 time(&chatstate_timestamp);
3133 } 3194 }
3134 return 0; 3195 return 0;
3135 } 3196 }
3136 3197
3198 #ifdef HAVE_ASPELL_H
3199 // Aspell initialization
3200 void spellcheck_init(void)
3201 {
3202 int aspell_enable = settings_opt_get_int("aspell_enable");
3203 const char *aspell_lang = settings_opt_get("aspell_lang");
3204 const char *aspell_encoding = settings_opt_get("aspell_encoding");
3205 AspellCanHaveError *possible_err;
3206
3207 if (!aspell_enable)
3208 return;
3209
3210 if (spell_checker) {
3211 delete_aspell_speller(spell_checker);
3212 delete_aspell_config(spell_config);
3213 spell_checker = NULL;
3214 spell_config = NULL;
3215 }
3216
3217 spell_config = new_aspell_config();
3218 aspell_config_replace(spell_config, "encoding", aspell_encoding);
3219 aspell_config_replace(spell_config, "lang", aspell_lang);
3220 possible_err = new_aspell_speller(spell_config);
3221
3222 if (aspell_error_number(possible_err) != 0) {
3223 spell_checker = NULL;
3224 delete_aspell_config(spell_config);
3225 spell_config = NULL;
3226 } else {
3227 spell_checker = to_aspell_speller(possible_err);
3228 }
3229 }
3230
3231 // Deinitialization of Aspell spellchecker
3232 void spellcheck_deinit(void)
3233 {
3234 if (spell_checker) {
3235 delete_aspell_speller(spell_checker);
3236 spell_checker = NULL;
3237 }
3238
3239 if (spell_config) {
3240 delete_aspell_config(spell_config);
3241 spell_config = NULL;
3242 }
3243 }
3244
3245 // Spell checking function
3246 static void spellcheck(char *line, char *checked)
3247 {
3248 const char *start, *line_start;
3249
3250 if (inputLine[0] == 0 || inputLine[0] == COMMAND_CHAR)
3251 return;
3252
3253 line_start = line;
3254
3255 while (*line) {
3256
3257 if (!is_alpha(line)) {
3258 line = next_char(line);
3259 continue;
3260 }
3261
3262 if (!strncmp(line, "http://", 7)) {
3263 line += 7; // : and / characters are 1 byte long in utf8, right?
3264
3265 while (!strchr(" \t\r\n", *line))
3266 line = next_char(line); // i think line++ would be fine here?
3267
3268 continue;
3269 }
3270
3271 if (!strncmp(line, "ftp://", 6)) {
3272 line += 6;
3273
3274 while (!strchr(" \t\r\n", *line))
3275 line = next_char(line);
3276
3277 continue;
3278 }
3279
3280 start = line;
3281
3282 while (is_alpha(line))
3283 line = next_char(line);
3284
3285 if (spell_checker &&
3286 aspell_speller_check(spell_checker, start, line - start) == 0)
3287 memset(&checked[start - line_start], ASPELLBADCHAR, line - start);
3288 }
3289 }
3290
3291 // Universal isalpha function
3292 static inline int is_alpha(const char *c)
3293 {
3294 if (utf8_mode) {
3295 if (iswalpha(get_char(c)))
3296 return 1;
3297 } else {
3298 if (isalpha(*c))
3299 return 1;
3300 }
3301 return 0;
3302 }
3303 #endif
3304
3137 /* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */ 3305 /* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */