Karsten Hopp 5a04c1
diff -ru vim70.orig/src/Makefile vim70.hunspell/src/Makefile
Karsten Hopp 5a04c1
--- vim70.orig/src/Makefile	2006-12-15 12:29:41.000000000 +0000
Karsten Hopp 5a04c1
+++ vim70.hunspell/src/Makefile	2006-12-14 11:11:20.000000000 +0000
Karsten Hopp 5a04c1
@@ -1287,7 +1287,7 @@
Karsten Hopp 5a04c1
 PFLAGS = $(PROTO_FLAGS) -DPROTO $(LINT_CFLAGS)
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
 ALL_LIB_DIRS = $(GUI_LIBS_DIR) $(X_LIBS_DIR)
Karsten Hopp 5a04c1
-ALL_LIBS = $(GUI_LIBS1) $(GUI_X_LIBS) $(GUI_LIBS2) $(X_PRE_LIBS) $(X_LIBS) $(X_EXTRA_LIBS) $(LIBS) $(EXTRA_LIBS) $(MZSCHEME_LIBS) $(PERL_LIBS) $(PYTHON_LIBS) $(TCL_LIBS) $(RUBY_LIBS) $(PROFILE_LIBS)
Karsten Hopp 5a04c1
+ALL_LIBS = $(GUI_LIBS1) $(GUI_X_LIBS) $(GUI_LIBS2) $(X_PRE_LIBS) $(X_LIBS) $(X_EXTRA_LIBS) $(LIBS) $(EXTRA_LIBS) $(MZSCHEME_LIBS) $(PERL_LIBS) $(PYTHON_LIBS) $(TCL_LIBS) $(RUBY_LIBS) $(PROFILE_LIBS) -lhunspell-1.1
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
 # abbreviations
Karsten Hopp 5a04c1
 DEST_BIN = $(DESTDIR)$(BINDIR)
Karsten Hopp 5a04c1
diff -ru vim70.orig/src/spell.c vim70.hunspell/src/spell.c
Karsten Hopp 5a04c1
--- vim70.orig/src/spell.c	2006-12-15 12:29:44.000000000 +0000
Karsten Hopp 5a04c1
+++ vim70.hunspell/src/spell.c	2006-12-15 12:27:49.000000000 +0000
Karsten Hopp 5a04c1
@@ -319,6 +319,8 @@
Karsten Hopp 5a04c1
 # include <time.h>	/* for time_t */
Karsten Hopp 5a04c1
 #endif
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
+#include "hunspell/hunspell.h"
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
 #define MAXWLEN 250		/* Assume max. word len is this many bytes.
Karsten Hopp 5a04c1
 				   Some places assume a word length fits in a
Karsten Hopp 5a04c1
 				   byte, thus it can't be above 255. */
Karsten Hopp 5a04c1
@@ -428,6 +430,8 @@
Karsten Hopp 5a04c1
 #define	SP_FORMERROR	-2	/* format error in spell file */
Karsten Hopp 5a04c1
 #define SP_OTHERERROR	-3	/* other error while reading spell file */
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
+#define MAXREGIONS 20
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
 /*
Karsten Hopp 5a04c1
  * Structure used to store words and other info for one language, loaded from
Karsten Hopp 5a04c1
  * a .spl file.
Karsten Hopp 5a04c1
@@ -450,6 +454,10 @@
Karsten Hopp 5a04c1
     char_u	*sl_name;	/* language name "en", "en.rare", "nl", etc. */
Karsten Hopp 5a04c1
     char_u	*sl_fname;	/* name of .spl file */
Karsten Hopp 5a04c1
     int		sl_add;		/* TRUE if it's a .add file. */
Karsten Hopp 5a04c1
+    int		sl_ishunspell;	/* TRUE if it's an unconverted hunspell aff/dic combination. */
Karsten Hopp 5a04c1
+    Hunhandle	*sl_hunspell;
Karsten Hopp 5a04c1
+    vimconv_T   sl_tohunconv;
Karsten Hopp 5a04c1
+    vimconv_T   sl_fromhunconv;
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
     char_u	*sl_fbyts;	/* case-folded word bytes */
Karsten Hopp 5a04c1
     idx_T	*sl_fidxs;	/* case-folded word indexes */
Karsten Hopp 5a04c1
@@ -460,7 +468,7 @@
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
     char_u	*sl_info;	/* infotext string or NULL */
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
-    char_u	sl_regions[17];	/* table with up to 8 region names plus NUL */
Karsten Hopp 5a04c1
+    char_u	sl_regions[MAXREGIONS * 2 + 1];	/* table with up to 8 region names plus NUL */
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
     char_u	*sl_midword;	/* MIDWORD string or NULL */
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
@@ -997,6 +1005,36 @@
Karsten Hopp 5a04c1
 static char_u	*repl_from = NULL;
Karsten Hopp 5a04c1
 static char_u	*repl_to = NULL;
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
+static void
Karsten Hopp 5a04c1
+ensurehunspellinit(lp)
Karsten Hopp 5a04c1
+    slang_T *lp;
Karsten Hopp 5a04c1
+{
Karsten Hopp 5a04c1
+    if (!lp->sl_hunspell)
Karsten Hopp 5a04c1
+    {
Karsten Hopp 5a04c1
+        char_u *dic = lp->sl_fname;
Karsten Hopp 5a04c1
+        char_u *aff = vim_strnsave(dic, strlen(dic));
Karsten Hopp 5a04c1
+    
Karsten Hopp 5a04c1
+	vim_strncpy(aff + strlen(aff) - 3, "aff", 3);
Karsten Hopp 5a04c1
+    
Karsten Hopp 5a04c1
+	lp->sl_hunspell = Hunspell_create(aff, dic);
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+	vim_free(aff);
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+	if (convert_setup(&lp->sl_tohunconv, spell_enc(), 
Karsten Hopp 5a04c1
+	    Hunspell_get_dic_encoding(lp->sl_hunspell)) == FAIL)
Karsten Hopp 5a04c1
+	{
Karsten Hopp 5a04c1
+	    lp->sl_tohunconv.vc_fail = TRUE;
Karsten Hopp 5a04c1
+	}
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+	if (convert_setup(&lp->sl_fromhunconv, 
Karsten Hopp 5a04c1
+	    Hunspell_get_dic_encoding(lp->sl_hunspell), spell_enc()) == FAIL)
Karsten Hopp 5a04c1
+	{
Karsten Hopp 5a04c1
+	    lp->sl_fromhunconv.vc_fail = TRUE;
Karsten Hopp 5a04c1
+	}
Karsten Hopp 5a04c1
+    }
Karsten Hopp 5a04c1
+}
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
 /*
Karsten Hopp 5a04c1
  * Main spell-checking function.
Karsten Hopp 5a04c1
  * "ptr" points to a character that could be the start of a word.
Karsten Hopp 5a04c1
@@ -1101,27 +1139,70 @@
Karsten Hopp 5a04c1
     {
Karsten Hopp 5a04c1
 	mi.mi_lp = LANGP_ENTRY(wp->w_buffer->b_langp, lpi);
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
+	if (mi.mi_lp->lp_slang->sl_ishunspell)
Karsten Hopp 5a04c1
+	{
Karsten Hopp 5a04c1
+	    slang_T *lp = mi.mi_lp->lp_slang;
Karsten Hopp 5a04c1
+	    char_u *converted = 0;
Karsten Hopp 5a04c1
+	    char_u *thisword;
Karsten Hopp 5a04c1
+	    char_u *mi_end = mi.mi_end;
Karsten Hopp 5a04c1
+	    char_u *mi_final =  mi.mi_word + strlen(mi.mi_word);
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+	    while (1)
Karsten Hopp 5a04c1
+	    {
Karsten Hopp 5a04c1
+		ensurehunspellinit(lp);
Karsten Hopp 5a04c1
+		if ((lp->sl_tohunconv.vc_fail == TRUE) || (lp->sl_fromhunconv.vc_fail == TRUE))
Karsten Hopp 5a04c1
+		    break;
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+		if (mi_end != mi.mi_word)
Karsten Hopp 5a04c1
+		{
Karsten Hopp 5a04c1
+		    thisword = vim_strnsave(mi.mi_word, mi_end - mi.mi_word);
Karsten Hopp 5a04c1
+		    converted = string_convert(&lp->sl_tohunconv, thisword, NULL);
Karsten Hopp 5a04c1
+		    if (converted)
Karsten Hopp 5a04c1
+		    {
Karsten Hopp 5a04c1
+			if (Hunspell_spell(lp->sl_hunspell, converted) != 0)
Karsten Hopp 5a04c1
+			{
Karsten Hopp 5a04c1
+			    mi.mi_result = SP_OK;
Karsten Hopp 5a04c1
+			    mi.mi_end = mi.mi_cend = mi.mi_word + strlen(thisword);
Karsten Hopp 5a04c1
+			}
Karsten Hopp 5a04c1
+			vim_free(converted);
Karsten Hopp 5a04c1
+		    }
Karsten Hopp 5a04c1
+		    vim_free(thisword);
Karsten Hopp 5a04c1
+		}
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+		if (mi_end == mi_final)
Karsten Hopp 5a04c1
+		    break;
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+		do
Karsten Hopp 5a04c1
+		{
Karsten Hopp 5a04c1
+		    mb_ptr_adv(mi_end);
Karsten Hopp 5a04c1
+		} while (*mi_end != NUL && spell_iswordp(mi_end, wp->w_buffer));
Karsten Hopp 5a04c1
+	    }
Karsten Hopp 5a04c1
+	}
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
 	/* If reloading fails the language is still in the list but everything
Karsten Hopp 5a04c1
 	 * has been cleared. */
Karsten Hopp 5a04c1
-	if (mi.mi_lp->lp_slang->sl_fidxs == NULL)
Karsten Hopp 5a04c1
+	if (!mi.mi_lp->lp_slang->sl_ishunspell && mi.mi_lp->lp_slang->sl_fidxs == NULL)
Karsten Hopp 5a04c1
 	    continue;
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
-	/* Check for a matching word in case-folded words. */
Karsten Hopp 5a04c1
-	find_word(&mi, FIND_FOLDWORD);
Karsten Hopp 5a04c1
+	if (!mi.mi_lp->lp_slang->sl_ishunspell)
Karsten Hopp 5a04c1
+	{
Karsten Hopp 5a04c1
+	    /* Check for a matching word in case-folded words. */
Karsten Hopp 5a04c1
+	    find_word(&mi, FIND_FOLDWORD);
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
-	/* Check for a matching word in keep-case words. */
Karsten Hopp 5a04c1
-	find_word(&mi, FIND_KEEPWORD);
Karsten Hopp 5a04c1
+	    /* Check for a matching word in keep-case words. */
Karsten Hopp 5a04c1
+	    find_word(&mi, FIND_KEEPWORD);
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
-	/* Check for matching prefixes. */
Karsten Hopp 5a04c1
-	find_prefix(&mi, FIND_FOLDWORD);
Karsten Hopp 5a04c1
+	    /* Check for matching prefixes. */
Karsten Hopp 5a04c1
+	    find_prefix(&mi, FIND_FOLDWORD);
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
-	/* For a NOBREAK language, may want to use a word without a following
Karsten Hopp 5a04c1
-	 * word as a backup. */
Karsten Hopp 5a04c1
-	if (mi.mi_lp->lp_slang->sl_nobreak && mi.mi_result == SP_BAD
Karsten Hopp 5a04c1
-						   && mi.mi_result2 != SP_BAD)
Karsten Hopp 5a04c1
-	{
Karsten Hopp 5a04c1
-	    mi.mi_result = mi.mi_result2;
Karsten Hopp 5a04c1
-	    mi.mi_end = mi.mi_end2;
Karsten Hopp 5a04c1
+	    /* For a NOBREAK language, may want to use a word without a following
Karsten Hopp 5a04c1
+	     * word as a backup. */
Karsten Hopp 5a04c1
+	    if (mi.mi_lp->lp_slang->sl_nobreak && mi.mi_result == SP_BAD
Karsten Hopp 5a04c1
+						       && mi.mi_result2 != SP_BAD)
Karsten Hopp 5a04c1
+	    {
Karsten Hopp 5a04c1
+		mi.mi_result = mi.mi_result2;
Karsten Hopp 5a04c1
+		mi.mi_end = mi.mi_end2;
Karsten Hopp 5a04c1
+	    }
Karsten Hopp 5a04c1
 	}
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
 	/* Count the word in the first language where it's found to be OK. */
Karsten Hopp 5a04c1
@@ -2359,6 +2440,80 @@
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
     if (r == FAIL)
Karsten Hopp 5a04c1
     {
Karsten Hopp 5a04c1
+#	define HUNSPELLDICT "/usr/share/myspell/"
Karsten Hopp 5a04c1
+	DIR *dirp = opendir(HUNSPELLDICT);
Karsten Hopp 5a04c1
+	if (dirp != NULL)
Karsten Hopp 5a04c1
+	{
Karsten Hopp 5a04c1
+	    slang_T* thislang[MAXREGIONS] = {0};
Karsten Hopp 5a04c1
+	    slang_T *lp = 0;
Karsten Hopp 5a04c1
+	    struct dirent *dp;
Karsten Hopp 5a04c1
+	    int i = 0;
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+	    while ((dp = readdir(dirp)) != NULL)
Karsten Hopp 5a04c1
+	    {
Karsten Hopp 5a04c1
+		char_u final_name[MAXPATHL];
Karsten Hopp 5a04c1
+		char_u spf_name[MAXPATHL];
Karsten Hopp 5a04c1
+		char_u thisregion[3] = {0};
Karsten Hopp 5a04c1
+		char *resolvedlink = final_name;
Karsten Hopp 5a04c1
+		int j, regionpos;
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+		if (strncmp(dp->d_name, lang, strlen(lang)) != 0)
Karsten Hopp 5a04c1
+		    continue;
Karsten Hopp 5a04c1
+		
Karsten Hopp 5a04c1
+		if ((strlen(dp->d_name) <= 4) || (dp->d_name[strlen(lang)] != '_'))
Karsten Hopp 5a04c1
+		    continue;
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+		if (strncmp(".dic", dp->d_name + strlen(dp->d_name) - 4, 4) != 0)
Karsten Hopp 5a04c1
+		    continue;
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+		vim_strncpy(spf_name, HUNSPELLDICT, strlen(HUNSPELLDICT));
Karsten Hopp 5a04c1
+		vim_strncpy(spf_name + strlen(HUNSPELLDICT), dp->d_name, strlen(HUNSPELLDICT));
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+		if (realpath(spf_name, resolvedlink) != resolvedlink)
Karsten Hopp 5a04c1
+		    continue;
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+		thisregion[0] = tolower(dp->d_name[strlen(lang)+1]);
Karsten Hopp 5a04c1
+		thisregion[1] = tolower(dp->d_name[strlen(lang)+1+1]);
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+		r = OK;
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+		for (j = 0; j < MAXREGIONS; ++j)
Karsten Hopp 5a04c1
+		{
Karsten Hopp 5a04c1
+		    if (thislang[j] && (strcmp(thislang[j]->sl_fname, final_name) == 0))
Karsten Hopp 5a04c1
+			break;
Karsten Hopp 5a04c1
+		}
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+		if (j < MAXREGIONS)
Karsten Hopp 5a04c1
+		    lp = thislang[j];
Karsten Hopp 5a04c1
+		else
Karsten Hopp 5a04c1
+		{
Karsten Hopp 5a04c1
+		    lp = slang_alloc(lang);
Karsten Hopp 5a04c1
+		    lp->sl_ishunspell = TRUE;
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+		    lp->sl_fname = vim_strsave(resolvedlink);
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+		    lp->sl_next = first_lang;
Karsten Hopp 5a04c1
+		    first_lang = lp;
Karsten Hopp 5a04c1
+		    thislang[i] = lp;
Karsten Hopp 5a04c1
+		}
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+		regionpos = 0;
Karsten Hopp 5a04c1
+		while (lp->sl_regions[regionpos] != 0) ++regionpos;
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+		//silently lose regions which won't fit in
Karsten Hopp 5a04c1
+		if (regionpos == MAXREGIONS * 2)
Karsten Hopp 5a04c1
+		    continue;
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+		vim_strncpy(lp->sl_regions + regionpos, thisregion, 2);
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+		++i;
Karsten Hopp 5a04c1
+	    }
Karsten Hopp 5a04c1
+	    closedir(dirp);
Karsten Hopp 5a04c1
+	}
Karsten Hopp 5a04c1
+    }
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+    if (r == FAIL)
Karsten Hopp 5a04c1
+    {
Karsten Hopp 5a04c1
 	smsg((char_u *)_("Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""),
Karsten Hopp 5a04c1
 						     lang, spell_enc(), lang);
Karsten Hopp 5a04c1
     }
Karsten Hopp 5a04c1
@@ -2429,6 +2584,9 @@
Karsten Hopp 5a04c1
 slang_free(lp)
Karsten Hopp 5a04c1
     slang_T	*lp;
Karsten Hopp 5a04c1
 {
Karsten Hopp 5a04c1
+    Hunspell_destroy(lp->sl_hunspell);
Karsten Hopp 5a04c1
+    convert_setup(&lp->sl_tohunconv, NULL, NULL);
Karsten Hopp 5a04c1
+    convert_setup(&lp->sl_fromhunconv, NULL, NULL);
Karsten Hopp 5a04c1
     vim_free(lp->sl_name);
Karsten Hopp 5a04c1
     vim_free(lp->sl_fname);
Karsten Hopp 5a04c1
     slang_clear(lp);
Karsten Hopp 5a04c1
@@ -2974,7 +3132,7 @@
Karsten Hopp 5a04c1
 {
Karsten Hopp 5a04c1
     int		i;
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
-    if (len > 16)
Karsten Hopp 5a04c1
+    if (len > MAXREGIONS*2)
Karsten Hopp 5a04c1
 	return SP_FORMERROR;
Karsten Hopp 5a04c1
     for (i = 0; i < len; ++i)
Karsten Hopp 5a04c1
 	lp->sl_regions[i] = getc(fd);			/* <regionname> */
Karsten Hopp 5a04c1
@@ -4112,6 +4270,7 @@
Karsten Hopp 5a04c1
     /* loop over comma separated language names. */
Karsten Hopp 5a04c1
     for (splp = buf->b_p_spl; *splp != NUL; )
Karsten Hopp 5a04c1
     {
Karsten Hopp 5a04c1
+	int hunspellregionunsupported;
Karsten Hopp 5a04c1
 	/* Get one language name. */
Karsten Hopp 5a04c1
 	copy_option_part(&splp, lang, MAXWLEN, ",");
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
@@ -4182,6 +4341,7 @@
Karsten Hopp 5a04c1
 	/*
Karsten Hopp 5a04c1
 	 * Loop over the languages, there can be several files for "lang".
Karsten Hopp 5a04c1
 	 */
Karsten Hopp 5a04c1
+	hunspellregionunsupported = 0;
Karsten Hopp 5a04c1
 	for (slang = first_lang; slang != NULL; slang = slang->sl_next)
Karsten Hopp 5a04c1
 	    if (filename ? fullpathcmp(lang, slang->sl_fname, FALSE) == FPC_SAME
Karsten Hopp 5a04c1
 			 : STRICMP(lang, slang->sl_name) == 0)
Karsten Hopp 5a04c1
@@ -4199,6 +4359,11 @@
Karsten Hopp 5a04c1
 				/* This addition file is for other regions. */
Karsten Hopp 5a04c1
 				region_mask = 0;
Karsten Hopp 5a04c1
 			}
Karsten Hopp 5a04c1
+			else if (slang->sl_ishunspell)
Karsten Hopp 5a04c1
+			{
Karsten Hopp 5a04c1
+			    region_mask = 0;
Karsten Hopp 5a04c1
+			    hunspellregionunsupported++;
Karsten Hopp 5a04c1
+			}
Karsten Hopp 5a04c1
 			else
Karsten Hopp 5a04c1
 			    /* This is probably an error.  Give a warning and
Karsten Hopp 5a04c1
 			     * accept the words anyway. */
Karsten Hopp 5a04c1
@@ -4207,7 +4372,10 @@
Karsten Hopp 5a04c1
 								      region);
Karsten Hopp 5a04c1
 		    }
Karsten Hopp 5a04c1
 		    else
Karsten Hopp 5a04c1
+		    {
Karsten Hopp 5a04c1
+			hunspellregionunsupported--;
Karsten Hopp 5a04c1
 			region_mask = 1 << c;
Karsten Hopp 5a04c1
+		    }
Karsten Hopp 5a04c1
 		}
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
 		if (region_mask != 0)
Karsten Hopp 5a04c1
@@ -4225,6 +4393,9 @@
Karsten Hopp 5a04c1
 			nobreak = TRUE;
Karsten Hopp 5a04c1
 		}
Karsten Hopp 5a04c1
 	    }
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+	if (region && hunspellregionunsupported >= 1)
Karsten Hopp 5a04c1
+	    smsg((char_u *) _("Warning: region %s not supported"), region);
Karsten Hopp 5a04c1
     }
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
     /* round 0: load int_wordlist, if possible.
Karsten Hopp 5a04c1
@@ -4832,7 +5003,7 @@
Karsten Hopp 5a04c1
     char_u	*si_info;	/* info text chars or NULL  */
Karsten Hopp 5a04c1
     int		si_region_count; /* number of regions supported (1 when there
Karsten Hopp 5a04c1
 				    are no regions) */
Karsten Hopp 5a04c1
-    char_u	si_region_name[16]; /* region names; used only if
Karsten Hopp 5a04c1
+    char_u	si_region_name[MAXREGIONS*2]; /* region names; used only if
Karsten Hopp 5a04c1
 				     * si_region_count > 1) */
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
     garray_T	si_rep;		/* list of fromto_T entries from REP lines */
Karsten Hopp 5a04c1
@@ -7093,7 +7264,7 @@
Karsten Hopp 5a04c1
 		else
Karsten Hopp 5a04c1
 		{
Karsten Hopp 5a04c1
 		    line += 8;
Karsten Hopp 5a04c1
-		    if (STRLEN(line) > 16)
Karsten Hopp 5a04c1
+		    if (STRLEN(line) > MAXREGIONS)
Karsten Hopp 5a04c1
 			smsg((char_u *)_("Too many regions in %s line %d: %s"),
Karsten Hopp 5a04c1
 						       fname, lnum, line);
Karsten Hopp 5a04c1
 		    else
Karsten Hopp 5a04c1
@@ -8973,7 +9144,7 @@
Karsten Hopp 5a04c1
     char_u	wfname[MAXPATHL];
Karsten Hopp 5a04c1
     char_u	**innames;
Karsten Hopp 5a04c1
     int		incount;
Karsten Hopp 5a04c1
-    afffile_T	*(afile[8]);
Karsten Hopp 5a04c1
+    afffile_T	*(afile[MAXREGIONS]);
Karsten Hopp 5a04c1
     int		i;
Karsten Hopp 5a04c1
     int		len;
Karsten Hopp 5a04c1
     struct stat	st;
Karsten Hopp 5a04c1
@@ -9040,8 +9211,8 @@
Karsten Hopp 5a04c1
 	EMSG(_(e_invarg));	/* need at least output and input names */
Karsten Hopp 5a04c1
     else if (vim_strchr(gettail(wfname), '_') != NULL)
Karsten Hopp 5a04c1
 	EMSG(_("E751: Output file name must not have region name"));
Karsten Hopp 5a04c1
-    else if (incount > 8)
Karsten Hopp 5a04c1
-	EMSG(_("E754: Only up to 8 regions supported"));
Karsten Hopp 5a04c1
+    else if (incount > MAXREGIONS)
Karsten Hopp 5a04c1
+	EMSG2(_("E754: Only up to %d regions supported"), MAXREGIONS);
Karsten Hopp 5a04c1
     else
Karsten Hopp 5a04c1
     {
Karsten Hopp 5a04c1
 	/* Check for overwriting before doing things that may take a lot of
Karsten Hopp 5a04c1
@@ -11097,6 +11268,36 @@
Karsten Hopp 5a04c1
     {
Karsten Hopp 5a04c1
 	lp = LANGP_ENTRY(curbuf->b_langp, lpi);
Karsten Hopp 5a04c1
 
Karsten Hopp 5a04c1
+	if (lp->lp_slang->sl_ishunspell)
Karsten Hopp 5a04c1
+	{
Karsten Hopp 5a04c1
+	    slang_T *slp = lp->lp_slang;
Karsten Hopp 5a04c1
+	    char **slst;
Karsten Hopp 5a04c1
+	    char_u *converted = 0;
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+	    ensurehunspellinit(slp);
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
+	    converted = string_convert(&slp->sl_tohunconv, su->su_fbadword, NULL);
Karsten Hopp 5a04c1
+	    if (converted)
Karsten Hopp 5a04c1
+	    {
Karsten Hopp 5a04c1
+		int suggests;
Karsten Hopp 5a04c1
+		suggests = Hunspell_suggest(slp->sl_hunspell, &slst, converted);
Karsten Hopp 5a04c1
+		if (suggests > 0)
Karsten Hopp 5a04c1
+		{
Karsten Hopp 5a04c1
+		    int i;
Karsten Hopp 5a04c1
+		    char_u *suggest;
Karsten Hopp 5a04c1
+		    for (i = 0; i < suggests; ++i)
Karsten Hopp 5a04c1
+		    {
Karsten Hopp 5a04c1
+			suggest = string_convert(&slp->sl_fromhunconv, slst[i], NULL);
Karsten Hopp 5a04c1
+			add_suggestion(su, &su->su_ga, suggest, su->su_badlen, i, 0, FALSE,
Karsten Hopp 5a04c1
+			    slp, FALSE);
Karsten Hopp 5a04c1
+			vim_free(suggest);
Karsten Hopp 5a04c1
+		    }
Karsten Hopp 5a04c1
+		    free(slst);
Karsten Hopp 5a04c1
+		}
Karsten Hopp 5a04c1
+		vim_free(converted);
Karsten Hopp 5a04c1
+	    }
Karsten Hopp 5a04c1
+	}
Karsten Hopp 5a04c1
+
Karsten Hopp 5a04c1
 	/* If reloading a spell file fails it's still in the list but
Karsten Hopp 5a04c1
 	 * everything has been cleared. */
Karsten Hopp 5a04c1
 	if (lp->lp_slang->sl_fbyts == NULL)