summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Filelist2
-rw-r--r--runtime/doc/eval.txt11
-rw-r--r--runtime/doc/spell.txt50
-rw-r--r--runtime/doc/tags6
-rw-r--r--runtime/lang/menu_sv_se.latin1.vim18
-rw-r--r--runtime/spell/en.latin1.splbin1103511 -> 1103766 bytes
-rwxr-xr-xsrc/auto/configure9
-rw-r--r--src/charset.c405
-rw-r--r--src/config.h.in2
-rw-r--r--src/configure.in5
-rw-r--r--src/option.c28
-rw-r--r--src/proto/spell.pro1
-rw-r--r--src/screen.c5
-rw-r--r--src/spell/Makefile93
-rw-r--r--src/spell/en_GB.diff2268
-rw-r--r--src/spell/en_US.diff102
-rw-r--r--src/spell/fr_FR.diff11
-rw-r--r--src/spell/nl_NL.diff153
-rw-r--r--src/spell/pl_PL.diff10
-rw-r--r--src/version.h4
20 files changed, 3091 insertions, 92 deletions
diff --git a/Filelist b/Filelist
index 870b893b4a..a4575c1ccc 100644
--- a/Filelist
+++ b/Filelist
@@ -122,6 +122,8 @@ SRC_ALL2 = \
src/proto/undo.pro \
src/proto/version.pro \
src/proto/window.pro \
+ src/spell/*.diff \
+ src/spell/Makefile \
# source files for Unix only
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index a0e446fcbe..d9020a741a 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt* For Vim version 7.0aa. Last change: 2005 Apr 04
+*eval.txt* For Vim version 7.0aa. Last change: 2005 Apr 22
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -338,6 +338,10 @@ Functions that are useful with a List: >
:let s = string(list) " String representation of list
:call map(list, '">> " . v:val') " prepend ">> " to each item
+Don't forget that a combination of features can make things simple. For
+example, to add up all the numbers in a list: >
+ :exe 'let sum = ' . join(nrlist, '+')
+
1.4 Dictionaries ~
*Dictionaries* *Dictionary*
@@ -3719,7 +3723,10 @@ split({expr} [, {pattern}]) *split()*
it makes the function work a bit faster.
To split a string in individual characters: >
:for c in split(mystring, '\zs')
-< The opposite function is |join()|.
+< If you want to keep the separator you can also use '\zs': >
+ :echo split('abc:def:ghi', ':\zs')
+< ['abc:', 'def:', 'ghi'] ~
+ The opposite function is |join()|.
strftime({format} [, {time}]) *strftime()*
diff --git a/runtime/doc/spell.txt b/runtime/doc/spell.txt
index 0f359a4c08..906e5cc983 100644
--- a/runtime/doc/spell.txt
+++ b/runtime/doc/spell.txt
@@ -1,4 +1,4 @@
-*spell.txt* For Vim version 7.0aa. Last change: 2005 Apr 20
+*spell.txt* For Vim version 7.0aa. Last change: 2005 Apr 23
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -160,16 +160,19 @@ procedure is recommended:
1. Obtain the xx_YY.aff and xx_YY.dic files from Myspell.
2. Make a copy of these files to xx_YY.orig.aff and xx_YY.orig.dic.
3. Change the xx_YY.aff and xx_YY.dic files to remove bad words, add missing
- words, etc.
-4. Use |:mkspell| to generate the Vim spell file and try it out.
+ words, define word characters with FOL/LOW/UPP, etc. The distributed
+ "src/spell/*.diff" files can be used.
+4. Set 'encoding' to the desired encoding and use |:mkspell| to generate the
+ Vim spell file.
+5. Try out the spell file with ":set spell spelllang=xx_YY".
When the Myspell files are updated you can merge the differences:
-5. Obtain the new Myspell files as xx_YY.new.aff and xx_UU.new.dic.
-6. Use Vimdiff to see what changed: >
+1. Obtain the new Myspell files as xx_YY.new.aff and xx_UU.new.dic.
+2. Use Vimdiff to see what changed: >
vimdiff xx_YY.orig.dic xx_YY.new.dic
-7. Take over the changes you like in xx_YY.dic.
+3. Take over the changes you like in xx_YY.dic.
You may also need to change xx_YY.aff.
-8. Rename xx_YY.new.dic to xx_YY.orig.dic and xx_YY.new.aff to xx_YY.new.aff.
+4. Rename xx_YY.new.dic to xx_YY.orig.dic and xx_YY.new.aff to xx_YY.new.aff.
==============================================================================
9. Spell file format *spell-file-format*
@@ -272,5 +275,38 @@ Performance hint: Although using affixes reduces the number of words, it
reduces the speed. It's a good idea to put all the often used words in the
word list with the affixes prepended/appended.
+ *spell-affix-chars*
+The affix file should define the word characters when using an 8-bit encoding
+(as specified with ENC). This is because the system where ":mkspell" is used
+may not support a locale with this encoding and isalpha() won't work. For
+example when using "cp1250" on Unix.
+
+ *E761* *E762*
+Three lines in the affix file are needed. Simplistic example:
+
+ FOL áëñáëñ
+ LOW áëñáëñ
+ UPP áëñÁËÑ
+
+All three lines must have exactly the same number of characters.
+
+The "FOL" line specifies the case-folded characters. These are used to
+compare words while ignoring case. For most encodings this is identical to
+the lower case line.
+
+The "LOW" line specifies the characters in lower-case. Mostly it's equal to
+the "FOL" line.
+
+The "UPP" line specifies the characters with upper-case. That is, a character
+is upper-case where it's different from the character at the same position in
+"FOL".
+
+ASCII characters should be omitted, Vim always handles these in the same way.
+When the encoding is UTF-8 no word characters need to be specified.
+
+ *E763*
+All spell files for the same encoding must use the same word characters,
+otherwise they can't be combined without errors.
+
vim:tw=78:sw=4:ts=8:ft=help:norl:
diff --git a/runtime/doc/tags b/runtime/doc/tags
index f9c52519ef..d86423aba3 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -3697,6 +3697,9 @@ E758 spell.txt /*E758*
E759 spell.txt /*E759*
E76 pattern.txt /*E76*
E760 spell.txt /*E760*
+E761 spell.txt /*E761*
+E762 spell.txt /*E762*
+E763 spell.txt /*E763*
E77 message.txt /*E77*
E78 motion.txt /*E78*
E79 message.txt /*E79*
@@ -4218,6 +4221,7 @@ blockwise-operators visual.txt /*blockwise-operators*
blockwise-register change.txt /*blockwise-register*
blockwise-visual visual.txt /*blockwise-visual*
book intro.txt /*book*
+bookmark usr_03.txt /*bookmark*
boolean options.txt /*boolean*
break-finally eval.txt /*break-finally*
browse() eval.txt /*browse()*
@@ -5113,7 +5117,6 @@ hebrew hebrew.txt /*hebrew*
hebrew.txt hebrew.txt /*hebrew.txt*
help various.txt /*help*
help-context help.txt /*help-context*
-help-tags tags 1
help-translated various.txt /*help-translated*
help-xterm-window various.txt /*help-xterm-window*
help.txt help.txt /*help.txt*
@@ -6230,6 +6233,7 @@ spec_chglog_release_info pi_spec.txt /*spec_chglog_release_info*
special-buffers windows.txt /*special-buffers*
speed-up tips.txt /*speed-up*
spell spell.txt /*spell*
+spell-affix-chars spell.txt /*spell-affix-chars*
spell-affix-mbyte spell.txt /*spell-affix-mbyte*
spell-affix-vim spell.txt /*spell-affix-vim*
spell-file-format spell.txt /*spell-file-format*
diff --git a/runtime/lang/menu_sv_se.latin1.vim b/runtime/lang/menu_sv_se.latin1.vim
index abeb562a29..e436d948c2 100644
--- a/runtime/lang/menu_sv_se.latin1.vim
+++ b/runtime/lang/menu_sv_se.latin1.vim
@@ -1,6 +1,6 @@
" Menu Translations: Swedish
-" Maintainer: Johan Svedberg <johan@svedberg.pp.se>
-" Last Change: 2004 May 16
+" Maintainer: Johan Svedberg <johan@svedberg.com>
+" Last Change: 2005 April 23
" Quit when menu translations have already been done.
if exists("did_menu_trans")
@@ -17,12 +17,13 @@ endif
" Help menu
menutrans &Help &Hjälp
menutrans &Overview<Tab><F1> &Översikt<Tab><F1>
-menutrans &How-to\ links &Hur-göra-länkar
menutrans &User\ Manual &Användarmanual
-"menutrans &GUI &GUI
+menutrans &How-to\ links &Hur-göra-länkar
+menutrans &Find\.\.\. &Sök\.\.\.
menutrans &Credits &Tack
menutrans Co&pying &Kopieringsrättigheter
-menutrans &Find\.\.\. &Sök\.\.\.
+menutrans &Sponsor/Register &Sponsra/Registrering
+menutrans O&rphans F&örälderlösa
menutrans &Version &Version
menutrans &About &Om
@@ -50,7 +51,7 @@ menutrans &Copy<Tab>"+y &Kopiera<Tab>"+y
menutrans &Paste<Tab>"+gP Klistra &in<Tab>"+gP
menutrans Put\ &Before<Tab>[p Sätt\ in\ &före<Tab>[p
menutrans Put\ &After<Tab>]p Sätt\ in\ &efter<Tab>]p
-menutrans &Select\ all<Tab>ggVG &Markera\ allt<Tab>ggVG
+menutrans &Select\ All<Tab>ggVG &Markera\ allt<Tab>ggVG
menutrans &Find\.\.\. &Sök\.\.\.
menutrans &Find<Tab>/ &Sök<Tab>/
menutrans Find\ and\ Rep&lace\.\.\. Sök\ och\ ersätt\.\.\.
@@ -75,6 +76,7 @@ menutrans Insert\ mode Infogningsläge
menutrans Block\ and\ Insert Block\ och\ infogning
menutrans Always Alltid
menutrans Toggle\ Insert\ &Mode<Tab>:set\ im! Växla\ infogningsläge<Tab>:set\ im!
+menutrans Toggle\ Vi\ C&ompatible<Tab>:set\ cp! Växla\ Vi-kompatibelitet<Tab>:set\ cp!
menutrans Search\ &Path\.\.\. Sökväg\.\.\.
menutrans Ta&g\ Files\.\.\. Taggfiler\.\.\.
menutrans Toggle\ &Toolbar Växla\ verktygsrad
@@ -91,6 +93,8 @@ menutrans Toggle\ W&rap\ at\ word<Tab>:set\ lbr! Växla\ radbrytning\ vid\ ord<ta
menutrans Toggle\ &expand-tab<Tab>:set\ et! Växla\ tab-expandering<Tab>:set\ et!
menutrans Toggle\ &auto-indent<Tab>:set\ ai! Växla\ auto-indentering<Tab>:set\ ai!
menutrans Toggle\ &C-indenting<Tab>:set\ cin! Växla\ C-indentering<Tab>:set\ cin!
+menutrans &Shiftwidth &Shiftbredd
+menutrans Soft\ &Tabstop Mjuka\ &Tabbstopp
menutrans Te&xt\ Width\.\.\. Textbredd\.\.\.
menutrans &File\ Format\.\.\. Filformat\.\.\.
@@ -123,7 +127,7 @@ menutrans &Close\ all\ folds<Tab>zM Stäng\ alla\ veck<Tab>zM
menutrans O&pen\ more\ folds<Tab>zr Öppna\ mer\ veck<Tab>zr
menutrans &Open\ all\ folds<Tab>zR Öppna\ mer\ veck<Tab>zR
menutrans Fold\ Met&hod Veckmetod
-menutrans M&anual Manual
+menutrans M&anual Manuell
menutrans I&ndent Indentering
menutrans E&xpression Uttryck
menutrans S&yntax Syntax
diff --git a/runtime/spell/en.latin1.spl b/runtime/spell/en.latin1.spl
index d9640c73bd..78de0c617a 100644
--- a/runtime/spell/en.latin1.spl
+++ b/runtime/spell/en.latin1.spl
Binary files differ
diff --git a/src/auto/configure b/src/auto/configure
index f22fee3d80..2d36fa835e 100755
--- a/src/auto/configure
+++ b/src/auto/configure
@@ -4629,7 +4629,7 @@ fi
if test "X$vi_cv_path_ruby" != "X"; then
echo "$as_me:$LINENO: checking Ruby version" >&5
echo $ECHO_N "checking Ruby version... $ECHO_C" >&6
- if $vi_cv_path_ruby -e 'RUBY_VERSION >= "1.6.0" or exit 1' >/dev/null 2>/dev/null; then
+ if $vi_cv_path_ruby -e '(VERSION rescue RUBY_VERSION) >= "1.6.0" or exit 1' >/dev/null 2>/dev/null; then
echo "$as_me:$LINENO: result: OK" >&5
echo "${ECHO_T}OK" >&6
echo "$as_me:$LINENO: checking Ruby header files" >&5
@@ -10989,6 +10989,7 @@ fi
+
for ac_header in stdarg.h stdlib.h string.h sys/select.h sys/utsname.h \
termcap.h fcntl.h sgtty.h sys/ioctl.h sys/time.h termio.h \
iconv.h langinfo.h unistd.h stropts.h errno.h \
@@ -10996,7 +10997,7 @@ for ac_header in stdarg.h stdlib.h string.h sys/select.h sys/utsname.h \
sys/stream.h sys/ptem.h termios.h libc.h sys/statfs.h \
poll.h sys/poll.h pwd.h utime.h sys/param.h libintl.h \
libgen.h util/debug.h util/msg18n.h frame.h \
- sys/acl.h sys/access.h sys/sysctl.h sys/sysinfo.h wchar.h
+ sys/acl.h sys/access.h sys/sysctl.h sys/sysinfo.h wchar.h wctype.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
@@ -13372,12 +13373,14 @@ fi
+
for ac_func in bcmp fchdir fchown fseeko fsync ftello getcwd getpseudotty \
getpwnam getpwuid getrlimit gettimeofday getwd lstat memcmp \
memset nanosleep opendir putenv qsort readlink select setenv \
setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \
sigvec snprintf strcasecmp strerror strftime stricmp strncasecmp \
- strnicmp strpbrk strtol tgetent towlower towupper usleep utime utimes
+ strnicmp strpbrk strtol tgetent towlower towupper iswupper \
+ usleep utime utimes
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
diff --git a/src/charset.c b/src/charset.c
index a82a7264ba..00a5326c89 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -915,97 +915,280 @@ vim_iswordc_buf(p, buf)
return (GET_CHARTAB(buf, *p) != 0);
}
-static char spell_chartab[256];
+/*
+ * The tables used for spelling. These are only used for the first 256
+ * characters.
+ */
+typedef struct spelltab_S
+{
+ char_u st_isw[256]; /* flags: is word char */
+ char_u st_isu[256]; /* flags: is uppercase char */
+ char_u st_fold[256]; /* chars: folded case */
+} spelltab_T;
+
+static spelltab_T spelltab;
+static int did_set_spelltab;
+
+#define SPELL_ISWORD 1
+#define SPELL_ISUPPER 2
+
+static void clear_spell_chartab __ARGS((spelltab_T *sp));
+static int set_spell_finish __ARGS((spelltab_T *new_st));
+
+/*
+ * Init the chartab used for spelling for ASCII.
+ * EBCDIC is not supported!
+ */
+ static void
+clear_spell_chartab(sp)
+ spelltab_T *sp;
+{
+ int i;
+
+ /* Init everything to FALSE. */
+ vim_memset(sp->st_isw, FALSE, sizeof(sp->st_isw));
+ vim_memset(sp->st_isu, FALSE, sizeof(sp->st_isu));
+ for (i = 0; i < 256; ++i)
+ sp->st_fold[i] = i;
+
+ /* We include digits. A word shouldn't start with a digit, but handling
+ * that is done separately. */
+ for (i = '0'; i <= '9'; ++i)
+ sp->st_isw[i] = TRUE;
+ for (i = 'A'; i <= 'Z'; ++i)
+ {
+ sp->st_isw[i] = TRUE;
+ sp->st_isu[i] = TRUE;
+ sp->st_fold[i] = i + 0x20;
+ }
+ for (i = 'a'; i <= 'z'; ++i)
+ sp->st_isw[i] = TRUE;
+}
/*
* Init the chartab used for spelling. Only depends on 'encoding'.
- * Called once while starting up and when 'encoding' was changed.
- * Unfortunately, we can't use isalpha() here, since the current locale may
- * differ from 'encoding'.
+ * Called once while starting up and when 'encoding' changes.
+ * The default is to use isalpha(), but the spell file should define the word
+ * characters to make it possible that 'encoding' differs from the current
+ * locale.
*/
void
init_spell_chartab()
{
int i;
- /* ASCII is always the same, no matter what 'encoding' is used.
- * EBCDIC is not supported! */
- for (i = 0; i < '0'; ++i)
- spell_chartab[i] = FALSE;
- /* We include numbers. A word shouldn't start with a number, but handling
- * that is done separately. */
- for ( ; i <= '9'; ++i)
- spell_chartab[i] = TRUE;
- for ( ; i < 'A'; ++i)
- spell_chartab[i] = FALSE;
- for ( ; i <= 'Z'; ++i)
- spell_chartab[i] = TRUE;
- for ( ; i < 'a'; ++i)
- spell_chartab[i] = FALSE;
- for ( ; i <= 'z'; ++i)
- spell_chartab[i] = TRUE;
+ did_set_spelltab = FALSE;
+ clear_spell_chartab(&spelltab);
+
#ifdef FEAT_MBYTE
if (enc_dbcs)
{
/* DBCS: assume double-wide characters are word characters. */
- for ( ; i <= 255; ++i)
+ for (i = 128; i <= 255; ++i)
if (MB_BYTE2LEN(i) == 2)
- spell_chartab[i] = TRUE;
- else
- spell_chartab[i] = FALSE;
+ spelltab.st_isw[i] = TRUE;
}
- else if (STRCMP(p_enc, "cp850") == 0)
+ else
#endif
-#if defined(MSDOS) || defined(FEAT_MBYTE)
{
- /* cp850, MS-DOS */
- for ( ; i < 128; ++i)
- spell_chartab[i] = FALSE;
- for ( ; i <= 0x9a; ++i)
- spell_chartab[i] = TRUE;
- for ( ; i < 0xa0; ++i)
- spell_chartab[i] = FALSE;
- for ( ; i <= 0xa5; ++i)
- spell_chartab[i] = TRUE;
- for ( ; i <= 255; ++i)
- spell_chartab[i] = FALSE;
+ /* Rough guess: use isalpha() for characters above 128. */
+ for (i = 128; i < 256; ++i)
+ {
+ spelltab.st_isw[i] = isalpha(i);
+ if (isupper(i))
+ {
+ spelltab.st_isu[i] = TRUE;
+ spelltab.st_fold[i] = tolower(i);
+ }
+ }
}
+}
+
+static char *e_affform = N_("E761: Format error in affix file FOL, LOW or UPP");
+static char *e_affrange = N_("E762: Character in FOL, LOW or UPP is out of range");
+
+/*
+ * Set the spell character tables from strings in the affix file.
+ */
+ int
+set_spell_chartab(fol, low, upp)
+ char_u *fol;
+ char_u *low;
+ char_u *upp;
+{
+ /* We build the new tables here first, so that we can compare with the
+ * previous one. */
+ spelltab_T new_st;
+ char_u *pf = fol, *pl = low, *pu = upp;
+ int f, l, u;
+
+ clear_spell_chartab(&new_st);
+
+ while (*pf != NUL)
+ {
+ if (*pl == NUL || *pu == NUL)
+ {
+ EMSG(_(e_affform));
+ return FAIL;
+ }
+#ifdef FEAT_MBYTE
+ f = mb_ptr2char_adv(&pf);
+ l = mb_ptr2char_adv(&pl);
+ u = mb_ptr2char_adv(&pu);
+#else
+ f = *pf++;
+ l = *pl++;
+ u = *pu++;
#endif
+ /* Every character that appears is a word character. */
+ if (f < 256)
+ new_st.st_isw[f] = TRUE;
+ if (l < 256)
+ new_st.st_isw[l] = TRUE;
+ if (u < 256)
+ new_st.st_isw[u] = TRUE;
+
+ /* if "LOW" and "FOL" are not the same the "LOW" char needs
+ * case-folding */
+ if (l < 256 && l != f)
+ {
+ if (f >= 256)
+ {
+ EMSG(_(e_affrange));
+ return FAIL;
+ }
+ new_st.st_fold[l] = f;
+ }
+
+ /* if "UPP" and "FOL" are not the same the "UPP" char needs
+ * case-folding and it's upper case. */
+ if (u < 256 && u != f)
+ {
+ if (f >= 256)
+ {
+ EMSG(_(e_affrange));
+ return FAIL;
+ }
+ new_st.st_fold[u] = f;
+ new_st.st_isu[u] = TRUE;
+ }
+ }
+
+ if (*pl != NUL || *pu != NUL)
+ {
+ EMSG(_(e_affform));
+ return FAIL;
+ }
+
+ return set_spell_finish(&new_st);
+}
+
+/*
+ * Set the spell character tables from strings in the .spl file.
+ */
+ int
+set_spell_charflags(flags, cnt, upp)
+ char_u *flags;
+ int cnt;
+ char_u *upp;
+{
+ /* We build the new tables here first, so that we can compare with the
+ * previous one. */
+ spelltab_T new_st;
+ int i;
+ char_u *p = upp;
+
+ clear_spell_chartab(&new_st);
+
+ for (i = 0; i < cnt; ++i)
+ {
+ new_st.st_isw[i + 128] = (flags[i] & SPELL_ISWORD) != 0;
+ new_st.st_isu[i + 128] = (flags[i] & SPELL_ISUPPER) != 0;
+
+ if (*p == NUL)
+ return FAIL;
#ifdef FEAT_MBYTE
- else if (STRCMP(p_enc, "iso-8859-2") == 0)
+ new_st.st_fold[i + 128] = mb_ptr2char_adv(&p);
+#else
+ new_st.st_fold[i + 128] = *p++;
+#endif
+ }
+
+ return set_spell_finish(&new_st);
+}
+
+ static int
+set_spell_finish(new_st)
+ spelltab_T *new_st;
+{
+ int i;
+
+ if (did_set_spelltab)
{
- /* latin2 */
- for ( ; i <= 0xa0; ++i)
- spell_chartab[i] = FALSE;
- for ( ; i <= 255; ++i)
- spell_chartab[i] = TRUE;
- spell_chartab[0xa4] = FALSE; /* currency sign */
- spell_chartab[0xa7] = FALSE; /* paragraph sign */
- spell_chartab[0xad] = FALSE; /* dash */
- spell_chartab[0xb0] = FALSE; /* degrees */
- spell_chartab[0xf7] = FALSE; /* divide-by */
+ /* check that it's the same table */
+ for (i = 0; i < 256; ++i)
+ {
+ if (spelltab.st_isw[i] != new_st->st_isw[i]
+ || spelltab.st_isu[i] != new_st->st_isu[i]
+ || spelltab.st_fold[i] != new_st->st_fold[i])
+ {
+ EMSG(_("E763: Word characters differ between spell files"));
+ return FAIL;
+ }
+ }
}
else
-#endif
-#if defined(FEAT_MBYTE) || !defined(MSDOS)
{
- /* Rough guess: anything we don't recognize assumes word characters
- * like latin1. */
- for ( ; i < 0xc0; ++i)
- spell_chartab[i] = FALSE;
- for ( ; i <= 255; ++i)
- spell_chartab[i] = TRUE;
-# ifdef FEAT_MBYTE
- if (STRCMP(p_enc, "latin1") == 0)
-# endif
- spell_chartab[0xf7] = FALSE; /* divide-by */
+ /* copy the new spelltab into the one being used */
+ spelltab = *new_st;
+ did_set_spelltab = TRUE;
}
-#endif
+
+ return OK;
+}
+
+#if defined(FEAT_MBYTE) || defined(PROTO)
+/*
+ * Write the current tables into the .spl file.
+ */
+ void
+write_spell_chartab(fd)
+ FILE *fd;
+{
+ char_u charbuf[256 * 4];
+ int len = 0;
+ int flags;
+ int i;
+
+ if (!did_set_spelltab)
+ {
+ /* No character table specified, write zero counts. */
+ fputc(0, fd);
+ fputc(0, fd);
+ fputc(0, fd);
+ return;
+ }
+
+ fputc(128, fd); /* <charflagslen> */
+ for (i = 128; i < 256; ++i)
+ {
+ flags = 0;
+ if (spelltab.st_isw[i])
+ flags |= SPELL_ISWORD;
+ if (spelltab.st_isu[i])
+ flags |= SPELL_ISUPPER;
+ fputc(flags, fd); /* <charflags> */
+
+ len += mb_char2bytes(spelltab.st_fold[i], charbuf + len);
+ }
+
+ put_bytes(fd, (long_u)len, 2); /* <fcharlen> */
+ fwrite(charbuf, (size_t)len, (size_t)1, fd); /* <fchars> */
}
+#endif
/*
- * Return TRUE if "p" points to a word character.
- * This only depends on 'encoding', not on 'iskeyword'.
+ * Return TRUE if "p" points to a word character for spelling.
*/
int
spell_iswordc(p)
@@ -1015,9 +1198,103 @@ spell_iswordc(p)
if (has_mbyte && MB_BYTE2LEN(*p) > 1)
return mb_get_class(p) >= 2;
# endif
- return spell_chartab[*p];
+ return spelltab.st_isw[*p];
+}
+
+/*
+ * Return TRUE if "c" is an upper-case character for spelling.
+ */
+ int
+spell_isupper(c)
+ int c;
+{
+# ifdef FEAT_MBYTE
+ if (enc_utf8)
+ {
+ /* For Unicode we can call utf_isupper(), but don't do that for ASCII,
+ * because we don't want to use 'casemap' here. */
+ if (c >= 128)
+ return utf_isupper(c);
+ }
+ else if (has_mbyte && c > 256)
+ {
+ /* For characters above 255 we don't have something specfied.
+ * Fall back to locale-dependent iswupper(). If not available
+ * simply return FALSE. */
+# ifdef HAVE_ISWUPPER
+ return iswupper(c);
+# else
+ return FALSE;
+# endif
+ }
+# endif
+ return spelltab.st_isu[c];
}
+
+/*
+ * case-fold "p[len]" into "buf[buflen]". Used for spell checking.
+ * Returns FAIL when something wrong.
+ */
+ int
+spell_casefold(p, len, buf, buflen)
+ char_u *p;
+ int len;
+ char_u *buf;
+ int buflen;
+{
+ int i;
+
+ if (len >= buflen)
+ {
+ buf[0] = NUL;
+ return FAIL; /* result will not fit */
+ }
+
+#ifdef FEAT_MBYTE
+ if (has_mbyte)
+ {
+ int c;
+ int outi = 0;
+
+ /* Fold one character at a time. */
+ for (i = 0; i < len; i += mb_ptr2len_check(p + i))
+ {
+ c = mb_ptr2char(p + i);
+ if (enc_utf8)
+ /* For Unicode case folding is always the same, no need to use
+ * the table from the spell file. */
+ c = utf_fold(c);
+ else if (c < 256)
+ /* Use the table from the spell file. */
+ c = spelltab.st_fold[c];
+# ifdef HAVE_TOWLOWER
+ else
+ /* We don't know what to do, fall back to towlower(), it
+ * depends on the current locale. */
+ c = towlower(c);
+# endif
+ if (outi + MB_MAXBYTES > buflen)
+ {
+ buf[outi] = NUL;
+ return FAIL;
+ }
+ outi += mb_char2bytes(c, buf + outi);
+ }
+ buf[outi] = NUL;
+ }
+ else
#endif
+ {
+ /* Be quick for non-multibyte encodings. */
+ for (i = 0; i < len; ++i)
+ buf[i] = spelltab.st_fold[p[i]];
+ buf[i] = NUL;
+ }
+
+ return OK;
+}
+
+#endif /* FEAT_SYN_HL */
/*
* return TRUE if 'c' is a valid file-name character
diff --git a/src/config.h.in b/src/config.h.in
index f9159aa547..0ecc7b1ec5 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -180,6 +180,7 @@
#undef HAVE_TGETENT
#undef HAVE_TOWLOWER
#undef HAVE_TOWUPPER
+#undef HAVE_ISWUPPER
#undef HAVE_USLEEP
#undef HAVE_UTIME
#undef HAVE_BIND_TEXTDOMAIN_CODESET
@@ -224,6 +225,7 @@
#undef HAVE_SYS_TIME_H
#undef HAVE_SYS_UTSNAME_H
#undef HAVE_WCHAR_H
+#undef HAVE_WCTYPE_H
#undef HAVE_TERMCAP_H
#undef HAVE_TERMIOS_H
#undef HAVE_TERMIO_H
diff --git a/src/configure.in b/src/configure.in
index fb8e330594..af18d880de 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -2245,7 +2245,7 @@ AC_CHECK_HEADERS(stdarg.h stdlib.h string.h sys/select.h sys/utsname.h \
sys/stream.h sys/ptem.h termios.h libc.h sys/statfs.h \
poll.h sys/poll.h pwd.h utime.h sys/param.h libintl.h \
libgen.h util/debug.h util/msg18n.h frame.h \
- sys/acl.h sys/access.h sys/sysctl.h sys/sysinfo.h wchar.h)
+ sys/acl.h sys/access.h sys/sysctl.h sys/sysinfo.h wchar.h wctype.h)
dnl pthread_np.h may exist but can only be used after including pthread.h
AC_MSG_CHECKING([for pthread_np.h])
@@ -2637,7 +2637,8 @@ AC_CHECK_FUNCS(bcmp fchdir fchown fseeko fsync ftello getcwd getpseudotty \
memset nanosleep opendir putenv qsort readlink select setenv \
setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \
sigvec snprintf strcasecmp strerror strftime stricmp strncasecmp \
- strnicmp strpbrk strtol tgetent towlower towupper usleep utime utimes)
+ strnicmp strpbrk strtol tgetent towlower towupper iswupper \
+ usleep utime utimes)
dnl fstatfs() can take 2 to 4 arguments, try to use st_blksize if possible
AC_MSG_CHECKING(for st_blksize)
diff --git a/src/option.c b/src/option.c
index cf5e9b407a..ee33df95ea 100644
--- a/src/option.c
+++ b/src/option.c
@@ -5658,10 +5658,20 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
#endif
#ifdef FEAT_SYN_HL
- /* When 'spelllang' is set, load the wordlists. */
+ /* When 'spelllang' is set and there is a window for this buffer in which
+ * 'spell' is set load the wordlists. */
else if (varp == &(curbuf->b_p_spl))
{
- errmsg = did_set_spelllang(curbuf);
+ win_T *wp;
+
+ FOR_ALL_WINDOWS(wp)
+ if (wp->w_buffer == curbuf && wp->w_p_spell)
+ {
+ errmsg = did_set_spelllang(curbuf);
+# ifdef FEAT_WINDOWS
+ break;
+# endif
+ }
}
#endif
@@ -6636,6 +6646,19 @@ set_bool_option(opt_idx, varp, value, opt_flags)
}
#endif
+#ifdef FEAT_SYN_HL
+ /* 'spell' */
+ else if ((int *)varp == &curwin->w_p_spell)
+ {
+ if (curwin->w_p_spell)
+ {
+ char_u *errmsg = did_set_spelllang(curbuf);
+ if (errmsg != NULL)
+ EMSG(_(errmsg));
+ }
+ }
+#endif
+
#ifdef FEAT_FKMAP
else if ((int *)varp == &p_altkeymap)
{
@@ -8586,7 +8609,6 @@ buf_copy_options(buf, flags)
/* Don't copy 'syntax', it must be set */
buf->b_p_syn = empty_option;
buf->b_p_spl = vim_strsave(p_spl);
- did_set_spelllang(buf);
#endif
#if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
buf->b_p_inde = vim_strsave(p_inde);
diff --git a/src/proto/spell.pro b/src/proto/spell.pro
index 5f91f4235a..e56eb92934 100644
--- a/src/proto/spell.pro
+++ b/src/proto/spell.pro
@@ -3,5 +3,6 @@ int spell_check __ARGS((win_T *wp, char_u *line, char_u *ptr, int *attrp));
int spell_move_to __ARGS((int dir, int allwords));
char_u *did_set_spelllang __ARGS((buf_T *buf));
void spell_reload __ARGS((void));
+void put_bytes __ARGS((FILE *fd, long_u nr, int len));
void ex_mkspell __ARGS((exarg_T *eap));
/* vim: set ft=c : */
diff --git a/src/screen.c b/src/screen.c
index b2e1181275..58fb4d029c 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -2603,7 +2603,10 @@ win_line(wp, lnum, startrow, endrow)
}
}
- if (wp->w_p_spell && *wp->w_buffer->b_p_spl != NUL)
+ if (wp->w_p_spell
+ && *wp->w_buffer->b_p_spl != NUL
+ && wp->w_buffer->b_langp.ga_len > 0
+ && *(char **)(wp->w_buffer->b_langp.ga_data) != NULL)
{
/* Prepare for spell checking. */
has_spell = TRUE;
diff --git a/src/spell/Makefile b/src/spell/Makefile
new file mode 100644
index 0000000000..ff5b75448a
--- /dev/null
+++ b/src/spell/Makefile
@@ -0,0 +1,93 @@
+# Makefile for Vim spell files.
+
+SPELLDIR = ../../runtime/spell
+VIM = ../vim
+
+all: en
+
+en: $(SPELLDIR)/en.latin1.spl \
+ $(SPELLDIR)/en.utf-8.spl \
+ $(SPELLDIR)/en.ascii.spl
+
+pl: $(SPELLDIR)/pl.iso-8859-2.spl \
+ $(SPELLDIR)/pl.utf-8.spl
+
+nl: $(SPELLDIR)/nl.latin1.spl \
+ $(SPELLDIR)/nl.utf-8.spl
+
+fr: $(SPELLDIR)/fr.latin1.spl \
+ $(SPELLDIR)/fr.utf-8.spl
+
+diff:
+ -diff -a -C 1 en_US.orig.aff en_US.aff >en_US.diff
+ -diff -a -C 1 en_US.orig.dic en_US.dic >>en_US.diff
+ -diff -a -C 1 en_AU.orig.aff en_AU.aff >en_AU.diff
+ -diff -a -C 1 en_AU.orig.dic en_AU.dic >>en_AU.diff
+ -diff -a -C 1 en_CA.orig.aff en_CA.aff >en_CA.diff
+ -diff -a -C 1 en_CA.orig.dic en_CA.dic >>en_CA.diff
+ -diff -a -C 1 en_GB.orig.aff en_GB.aff >en_GB.diff
+ -diff -a -C 1 en_GB.orig.dic en_GB.dic >>en_GB.diff
+ -diff -a -C 1 en_NZ.orig.aff en_NZ.aff >en_NZ.diff
+ -diff -a -C 1 en_NZ.orig.dic en_NZ.dic >>en_NZ.diff
+
+ -diff -a -C 1 nl_NL.orig.aff nl_NL.aff >nl_NL.diff
+ -diff -a -C 1 nl_NL.orig.dic nl_NL.dic >>nl_NL.diff
+
+ -diff -a -C 1 pl_PL.orig.aff pl_PL.aff >pl_PL.diff
+ -diff -a -C 1 pl_PL.orig.dic pl_PL.dic >>pl_PL.diff
+
+ -diff -a -C 1 fr_FR.orig.aff fr_FR.aff >fr_FR.diff
+ -diff -a -C 1 fr_FR.orig.dic fr_FR.dic >>fr_FR.diff
+
+$(SPELLDIR)/en.latin1.spl : $(VIM) \
+ en_US.aff en_US.dic \
+ en_AU.aff en_AU.dic \
+ en_CA.aff en_CA.dic \
+ en_GB.aff en_GB.dic \
+ en_NZ.aff en_NZ.dic
+ env LANG=en_US.ISO8859-1 \
+ $(VIM) -e -c "mkspell! $(SPELLDIR)/en en_US en_AU en_CA en_GB \
+ en_NZ" -c q
+
+$(SPELLDIR)/en.utf-8.spl : $(VIM) \
+ en_US.aff en_US.dic \
+ en_AU.aff en_AU.dic \
+ en_CA.aff en_CA.dic \
+ en_GB.aff en_GB.dic \
+ en_NZ.aff en_NZ.dic
+ env LANG=en_US.UTF-8 \
+ $(VIM) -e -c "mkspell! $(SPELLDIR)/en en_US en_AU en_CA en_GB \
+ en_NZ" -c q
+
+$(SPELLDIR)/en.ascii.spl : $(VIM) \
+ en_US.aff en_US.dic \
+ en_AU.aff en_AU.dic \
+ en_CA.aff en_CA.dic \
+ en_GB.aff en_GB.dic \
+ en_NZ.aff en_NZ.dic
+ $(VIM) -e -c "mkspell! -ascii $(SPELLDIR)/en en_US en_AU en_CA en_GB \
+ en_NZ" -c q
+
+$(SPELLDIR)/pl.iso-8859-2.spl : $(VIM) \
+ pl_PL.aff pl_PL.dic
+ env LANG=pl_PL.ISO8859-2 $(VIM) -e -c "mkspell! $(SPELLDIR)/pl pl_PL" -c q
+
+$(SPELLDIR)/pl.utf-8.spl : $(VIM) \
+ pl_PL.aff pl_PL.dic
+ env LANG=pl_PL.UTF-8 $(VIM) -e -c "mkspell! $(SPELLDIR)/pl pl_PL" -c q
+
+$(SPELLDIR)/nl.latin1.spl : $(VIM) \
+ nl_NL.aff nl_NL.dic
+ env LANG=nl_NL.ISO8859-1 $(VIM) -e -c "mkspell! $(SPELLDIR)/nl nl_NL" -c q
+
+$(SPELLDIR)/nl.utf-8.spl : $(VIM) \
+ nl_NL.aff nl_NL.dic
+ env LANG=nl_NL.UTF-8 $(VIM) -e -c "mkspell! $(SPELLDIR)/nl nl_NL" -c q
+
+$(SPELLDIR)/fr.latin1.spl : $(VIM) \
+ fr_FR.aff fr_FR.dic
+ env LANG=fr_FR.ISO8859-1 $(VIM) -e -c "mkspell! $(SPELLDIR)/fr fr_FR" -c q
+
+$(SPELLDIR)/fr.utf-8.spl : $(VIM) \
+ fr_FR.aff fr_FR.dic
+ env LANG=fr_FR.UTF-8 $(VIM) -e -c "mkspell! $(SPELLDIR)/fr fr_FR" -