# HG changeset patch # User entragian # Date 1175721817 -7200 # Node ID 0f7e0346d9cbca7dc03a0cf8e91f26807f0356ae # Parent 220e0481652479c6d18513ab3e2a80792939b8c5 Add aspell support [Note: Patch slightly modified by Mikael] diff -r 220e04816524 -r 0f7e0346d9cb mcabber/configure.ac --- a/mcabber/configure.ac Wed Apr 04 22:43:47 2007 +0200 +++ b/mcabber/configure.ac Wed Apr 04 23:23:37 2007 +0200 @@ -152,6 +152,24 @@ fi fi +# Check for Aspell stuff +AC_ARG_ENABLE(aspell, [ --enable-aspell Enable aspell support], + enable_aspell=$enableval, aspell="") +if test "x$enable_aspell" = "xyes"; then + AC_CHECK_HEADERS(aspell.h, [ have_aspell_includes=yes ]) + if test "x$have_aspell_includes" = "xyes"; then + AC_CHECK_LIB(aspell, new_aspell_config, [ have_aspell_libs=yes ]) + if test "x$have_aspell_libs" = "xyes"; then + AC_DEFINE(WITH_ASPELL, 1, [define if you want aspell support]) + LIBS="$LIBS -laspell" + else + enable_aspell=no + fi + else + enable_aspell=no + fi +fi + AC_DEFINE(BUILD_JABBER, 1, [build with jabber support]) # Export $datadir to the source tree. diff -r 220e04816524 -r 0f7e0346d9cb mcabber/src/main.c --- a/mcabber/src/main.c Wed Apr 04 22:43:47 2007 +0200 +++ b/mcabber/src/main.c Wed Apr 04 23:23:37 2007 +0200 @@ -376,6 +376,13 @@ if (optval || optval2) hlog_enable(optval, settings_opt_get("logging_dir"), optval2); +#ifdef HAVE_ASPELL_H + /* Initialize aspell */ + if (settings_opt_get_int("aspell_enable")) { + spellcheck_init(); + } +#endif + optstring = settings_opt_get("events_command"); if (optstring) hk_ext_cmd_init(optstring); @@ -422,6 +429,12 @@ gpg_terminate(); #endif scr_TerminateCurses(); +#ifdef HAVE_ASPELL_H + /* Deinitialize aspell */ + if (settings_opt_get_int("aspell_enable")) { + spellcheck_deinit(); + } +#endif printf("\n\nThanks for using mcabber!\n"); diff -r 220e04816524 -r 0f7e0346d9cb mcabber/src/screen.c --- a/mcabber/src/screen.c Wed Apr 04 22:43:47 2007 +0200 +++ b/mcabber/src/screen.c Wed Apr 04 23:23:37 2007 +0200 @@ -29,6 +29,10 @@ #include #include +#ifdef HAVE_ASPELL_H +# include +#endif + #include "screen.h" #include "utf8.h" #include "hbuf.h" @@ -56,6 +60,11 @@ static void scr_insert_text(const char*); static void scr_handle_tab(void); +#ifdef HAVE_ASPELL_H +static void spellcheck(char *, char *); +static inline int is_alpha(const char *); +#endif + static GHashTable *winbufhash; typedef struct { @@ -100,6 +109,9 @@ static time_t LastActivity; static char inputLine[INPUTLINE_LENGTH+1]; +#ifdef HAVE_ASPELL_H +static char maskLine[INPUTLINE_LENGTH+1]; +#endif static char *ptr_inputline; static short int inputline_offset; static int completion_started; @@ -127,6 +139,11 @@ void scr_WriteInWindow(const char *winId, const char *text, time_t timestamp, unsigned int prefix_flags, int force_show); +#ifdef HAVE_ASPELL_H +#define ASPELLBADCHAR 5 +AspellConfig *spell_config; +AspellSpeller *spell_checker; +#endif /* Functions */ @@ -2810,18 +2827,62 @@ inputline_offset = c - inputLine; } +#ifdef HAVE_ASPELL_H +// prints inputLine with underlined words when misspelled +static inline void print_checked_line(void) +{ + char *wprint_char_fmt = "%c"; + int point; + char *ptrCur = inputLine + inputline_offset; + +#ifdef UNICODE + // We need this to display a single UTF-8 char... Any better solution? + if (utf8_mode) + wprint_char_fmt = "%lc"; +#endif + + wmove(inputWnd, 0, 0); // problem with backspace + + while (*ptrCur) { + point = ptrCur - inputLine; + if (maskLine[point]) + wattrset(inputWnd, A_UNDERLINE); + wprintw(inputWnd, wprint_char_fmt, get_char(ptrCur)); + wattrset(inputWnd, A_NORMAL); + ptrCur = next_char(ptrCur); + } +} +#endif + static inline void refresh_inputline(void) { - mvwprintw(inputWnd, 0,0, "%s", inputLine + inputline_offset); +#ifdef HAVE_ASPELL_H + if (settings_opt_get_int("aspell_enable")) { + memset(maskLine, 0, INPUTLINE_LENGTH+1); + spellcheck(inputLine, maskLine); + } + print_checked_line(); wclrtoeol(inputWnd); if (*ptr_inputline) { // hack to set cursor pos. Characters can have different width, // so I know of no better way. char c = *ptr_inputline; *ptr_inputline = 0; - mvwprintw(inputWnd, 0,0, "%s", inputLine + inputline_offset); + print_checked_line(); *ptr_inputline = c; } +#else + mvwprintw(inputWnd, 0, 0, "%s", inputLine + inputline_offset); + wclrtoeol(inputWnd); + if (*ptr_inputline) { + // hack to set cursor pos. Characters can have different width, + // so I know of no better way. + char c = *ptr_inputline; + *ptr_inputline = 0; + mvwprintw(inputWnd, 0, 0, "%s", inputLine + inputline_offset); + *ptr_inputline = c; + } +#endif } void scr_handle_CtrlC(void) @@ -3134,4 +3195,111 @@ return 0; } +#ifdef HAVE_ASPELL_H +// Aspell initialization +void spellcheck_init(void) +{ + int aspell_enable = settings_opt_get_int("aspell_enable"); + const char *aspell_lang = settings_opt_get("aspell_lang"); + const char *aspell_encoding = settings_opt_get("aspell_encoding"); + AspellCanHaveError *possible_err; + + if (!aspell_enable) + return; + + if (spell_checker) { + delete_aspell_speller(spell_checker); + delete_aspell_config(spell_config); + spell_checker = NULL; + spell_config = NULL; + } + + spell_config = new_aspell_config(); + aspell_config_replace(spell_config, "encoding", aspell_encoding); + aspell_config_replace(spell_config, "lang", aspell_lang); + possible_err = new_aspell_speller(spell_config); + + if (aspell_error_number(possible_err) != 0) { + spell_checker = NULL; + delete_aspell_config(spell_config); + spell_config = NULL; + } else { + spell_checker = to_aspell_speller(possible_err); + } +} + +// Deinitialization of Aspell spellchecker +void spellcheck_deinit(void) +{ + if (spell_checker) { + delete_aspell_speller(spell_checker); + spell_checker = NULL; + } + + if (spell_config) { + delete_aspell_config(spell_config); + spell_config = NULL; + } +} + +// Spell checking function +static void spellcheck(char *line, char *checked) +{ + const char *start, *line_start; + + if (inputLine[0] == 0 || inputLine[0] == COMMAND_CHAR) + return; + + line_start = line; + + while (*line) { + + if (!is_alpha(line)) { + line = next_char(line); + continue; + } + + if (!strncmp(line, "http://", 7)) { + line += 7; // : and / characters are 1 byte long in utf8, right? + + while (!strchr(" \t\r\n", *line)) + line = next_char(line); // i think line++ would be fine here? + + continue; + } + + if (!strncmp(line, "ftp://", 6)) { + line += 6; + + while (!strchr(" \t\r\n", *line)) + line = next_char(line); + + continue; + } + + start = line; + + while (is_alpha(line)) + line = next_char(line); + + if (spell_checker && + aspell_speller_check(spell_checker, start, line - start) == 0) + memset(&checked[start - line_start], ASPELLBADCHAR, line - start); + } +} + +// Universal isalpha function +static inline int is_alpha(const char *c) +{ + if (utf8_mode) { + if (iswalpha(get_char(c))) + return 1; + } else { + if (isalpha(*c)) + return 1; + } + return 0; +} +#endif + /* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */ diff -r 220e04816524 -r 0f7e0346d9cb mcabber/src/screen.h --- a/mcabber/src/screen.h Wed Apr 04 22:43:47 2007 +0200 +++ b/mcabber/src/screen.h Wed Apr 04 23:23:37 2007 +0200 @@ -14,6 +14,12 @@ # include #endif +#ifdef WITH_ASPELL +void spellcheck_init(void); +void spellcheck_deinit(void); +//static void spellcheck(char*, char*); +#endif + #include "logprint.h" // Length of the timestamp & flag prefix in the chat buffer window diff -r 220e04816524 -r 0f7e0346d9cb mcabber/src/utf8.h --- a/mcabber/src/utf8.h Wed Apr 04 22:43:47 2007 +0200 +++ b/mcabber/src/utf8.h Wed Apr 04 23:23:37 2007 +0200 @@ -23,6 +23,7 @@ # define iswprint(c) isprint(c) # define towupper(c) toupper(c) # define towlower(c) tolower(c) +# define iswalpha(c) isalpha(c) #endif extern int utf8_mode;