changeset 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 0ff57f0730d0
files mcabber/configure.ac mcabber/src/main.c mcabber/src/screen.c mcabber/src/screen.h mcabber/src/utf8.h
diffstat 5 files changed, 208 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- 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.
--- 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");
 
--- 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 <langinfo.h>
 #include <config.h>
 
+#ifdef HAVE_ASPELL_H
+# include <aspell.h>
+#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... */
--- 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 <panel.h>
 #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
--- 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;