changeset 20802:ed00f0fbdaef v8.2.0953

patch 8.2.0953: spell checking doesn't work for CamelCased words Commit: https://github.com/vim/vim/commit/362b44bd4aa87a2aef0f8fd5a28d68dd09a7d909 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Jun 10 21:47:00 2020 +0200 patch 8.2.0953: spell checking doesn't work for CamelCased words Problem: Spell checking doesn't work for CamelCased words. Solution: Add the "camel" value in the new option 'spelloptions'. (closes #1235)
author Bram Moolenaar <Bram@vim.org>
date Wed, 10 Jun 2020 22:00:04 +0200
parents f69512e0cedc
children 0e5a27f1631c
files runtime/doc/options.txt runtime/doc/spell.txt src/buffer.c src/option.c src/option.h src/optiondefs.h src/optionstr.c src/testdir/gen_opt_test.vim src/testdir/test_spell.vim src/version.c
diffstat 10 files changed, 45 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -7105,6 +7105,16 @@ A jump table for the options with a shor
 	up to the first character that is not an ASCII letter or number and
 	not a dash.  Also see |set-spc-auto|.
 
+						*'spelloptions'* *'spo'*
+'spelloptions' 'spo'	string	(default "")
+			local to buffer
+			{not available when compiled without the |+syntax|
+			feature}
+	A comma separated list of options for spell checking:
+	   camel	When a word is CamelCased, assume "Cased" is a
+			separate word: every upper-case character in a word
+			that comes after a lower case character indicates the
+			start of a new word.
 
 						*'spellsuggest'* *'sps'*
 'spellsuggest' 'sps'	string	(default "best")
--- a/runtime/doc/spell.txt
+++ b/runtime/doc/spell.txt
@@ -215,6 +215,9 @@ When there is a line break right after a
 line may be postponed.  Use |CTRL-L| when needed.  Also see |set-spc-auto| for
 how it can be set automatically when 'spelllang' is set.
 
+The 'spelloptions' option has a few more flags that influence the way spell
+checking works.
+
 Vim counts the number of times a good word is encountered.  This is used to
 sort the suggestions: words that have been seen before get a small bonus,
 words that have been seen often get a bigger bonus.  The COMMON item in the
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2287,6 +2287,7 @@ free_buf_options(
     vim_regfree(buf->b_s.b_cap_prog);
     buf->b_s.b_cap_prog = NULL;
     clear_string_option(&buf->b_s.b_p_spl);
+    clear_string_option(&buf->b_s.b_p_spo);
 #endif
 #ifdef FEAT_SEARCHPATH
     clear_string_option(&buf->b_p_sua);
--- a/src/option.c
+++ b/src/option.c
@@ -5329,6 +5329,7 @@ get_varp(struct vimoption *p)
 	case PV_SPC:	return (char_u *)&(curwin->w_s->b_p_spc);
 	case PV_SPF:	return (char_u *)&(curwin->w_s->b_p_spf);
 	case PV_SPL:	return (char_u *)&(curwin->w_s->b_p_spl);
+	case PV_SPO:	return (char_u *)&(curwin->w_s->b_p_spo);
 #endif
 	case PV_SW:	return (char_u *)&(curbuf->b_p_sw);
 	case PV_TS:	return (char_u *)&(curbuf->b_p_ts);
@@ -5838,6 +5839,8 @@ buf_copy_options(buf_T *buf, int flags)
 	    COPY_OPT_SCTX(buf, BV_SPF);
 	    buf->b_s.b_p_spl = vim_strsave(p_spl);
 	    COPY_OPT_SCTX(buf, BV_SPL);
+	    buf->b_s.b_p_spo = vim_strsave(p_spo);
+	    COPY_OPT_SCTX(buf, BV_SPO);
 #endif
 #if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
 	    buf->b_p_inde = vim_strsave(p_inde);
--- a/src/option.h
+++ b/src/option.h
@@ -913,6 +913,7 @@ EXTERN char_u	*p_tfu;		// 'tagfunc'
 EXTERN char_u	*p_spc;		// 'spellcapcheck'
 EXTERN char_u	*p_spf;		// 'spellfile'
 EXTERN char_u	*p_spl;		// 'spelllang'
+EXTERN char_u	*p_spo;		// 'spelloptions'
 EXTERN char_u	*p_sps;		// 'spellsuggest'
 #endif
 EXTERN int	p_spr;		// 'splitright'
@@ -1185,6 +1186,7 @@ enum
     , BV_SPC
     , BV_SPF
     , BV_SPL
+    , BV_SPO
 #endif
     , BV_STS
 #ifdef FEAT_SEARCHPATH
--- a/src/optiondefs.h
+++ b/src/optiondefs.h
@@ -129,6 +129,7 @@
 # define PV_SPC		OPT_BUF(BV_SPC)
 # define PV_SPF		OPT_BUF(BV_SPF)
 # define PV_SPL		OPT_BUF(BV_SPL)
+# define PV_SPO		OPT_BUF(BV_SPO)
 #endif
 #define PV_STS		OPT_BUF(BV_STS)
 #ifdef FEAT_SEARCHPATH
@@ -2398,6 +2399,16 @@ static struct vimoption options[] =
 			    {(char_u *)0L, (char_u *)0L}
 #endif
 			    SCTX_INIT},
+    {"spelloptions", "spo",  P_STRING|P_ALLOCED|P_VI_DEF
+						    |P_ONECOMMA|P_NODUP|P_RBUF,
+#ifdef FEAT_SPELL
+			    (char_u *)&p_spo, PV_SPO,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    SCTX_INIT},
     {"spellsuggest", "sps", P_STRING|P_VI_DEF|P_EXPAND|P_SECURE|P_ONECOMMA,
 #ifdef FEAT_SPELL
 			    (char_u *)&p_sps, PV_NONE,
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -248,6 +248,7 @@ check_buf_options(buf_T *buf)
     check_string_option(&buf->b_s.b_p_spc);
     check_string_option(&buf->b_s.b_p_spf);
     check_string_option(&buf->b_s.b_p_spl);
+    check_string_option(&buf->b_s.b_p_spo);
 #endif
 #ifdef FEAT_SEARCHPATH
     check_string_option(&buf->b_p_sua);
@@ -1714,6 +1715,12 @@ did_set_string_option(
     {
 	errmsg = compile_cap_prog(curwin->w_s);
     }
+    // 'spelloptions'
+    else if (varp == &(curwin->w_s->b_p_spo))
+    {
+	if (**varp != NUL && STRCMP("camel", *varp) != 0)
+	    errmsg = e_invarg;
+    }
     // 'spellsuggest'
     else if (varp == &p_sps)
     {
--- a/src/testdir/gen_opt_test.vim
+++ b/src/testdir/gen_opt_test.vim
@@ -132,6 +132,7 @@ let test_values = {
       \ 'signcolumn': [['', 'auto', 'no'], ['xxx', 'no,yes']],
       \ 'spellfile': [['', 'file.en.add'], ['xxx', '/tmp/file']],
       \ 'spelllang': [['', 'xxx', 'sr@latin'], ['not&lang', "that\\\rthere"]],
+      \ 'spelloptions': [['', 'camel'], ['xxx']],
       \ 'spellsuggest': [['', 'best', 'double,33'], ['xxx']],
       \ 'switchbuf': [['', 'useopen', 'split,newtab'], ['xxx']],
       \ 'tagcase': [['smart', 'match'], ['', 'xxx', 'smart,match']],
--- a/src/testdir/test_spell.vim
+++ b/src/testdir/test_spell.vim
@@ -77,6 +77,11 @@ func Test_spellbadword()
   call assert_equal(['bycycle', 'bad'],  spellbadword('My bycycle.'))
   call assert_equal(['another', 'caps'], 'A sentence. another sentence'->spellbadword())
 
+  call assert_equal(['TheCamelWord', 'bad'], 'TheCamelWord asdf'->spellbadword())
+  set spelloptions=camel
+  call assert_equal(['asdf', 'bad'], 'TheCamelWord asdf'->spellbadword())
+  set spelloptions=
+
   set spelllang=en
   call assert_equal(['', ''],            spellbadword('centre'))
   call assert_equal(['', ''],            spellbadword('center'))
--- a/src/version.c
+++ b/src/version.c
@@ -755,6 +755,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    953,
+/**/
     952,
 /**/
     951,