From 30abd28f16a6c1ccc3263d49917e985ebab8fea9 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 22 Jun 2005 22:35:10 +0000 Subject: updated for version 7.0090 --- runtime/doc/spell.txt | 69 +++++++++++++++++++++++++++------ runtime/doc/tags | 3 +- runtime/doc/various.txt | 5 ++- runtime/ftplugin/c.vim | 6 ++- runtime/spell/en.latin1.spl | Bin 561966 -> 561958 bytes src/proto/spell.pro | 1 + src/screen.c | 92 ++++++++++++++++++++++++++++++++++++++++++-- src/syntax.c | 33 ++++++++-------- 8 files changed, 173 insertions(+), 36 deletions(-) diff --git a/runtime/doc/spell.txt b/runtime/doc/spell.txt index 7013e6d70..9a72f3b0d 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 Jun 21 +*spell.txt* For Vim version 7.0aa. Last change: 2005 Jun 22 VIM REFERENCE MANUAL by Bram Moolenaar @@ -41,7 +41,9 @@ To search for the next misspelled word: *[s* [s Like "]s" but search backwards, find the misspelled - word before the cursor. + word before the cursor. Doesn't recognize words + split over two lines, thus may stop at words that are + not highlighted as bad. *]S* ]S Like "]s" but only stop at bad words, not at rare @@ -77,12 +79,11 @@ automatically be updated. More details about the 'spellfile' format below Finding suggestions for bad words: *z?* -z? For the badly spelled word under the cursor suggest - the correctly spelled word. - When there is no badly spelled word under the cursor - use the one after the cursor, in the same line. - The results are sorted on similarity to the badly - spelled word. +z? For the word under/after the cursor suggest correctly + spelled words. This also works to find alternative + for words that are not highlighted as bad words. + The results are sorted on similarity to the word + under/after the cursor. This may take a long time. Hit CTRL-C when you are bored. You can enter the number of your choice or press @@ -90,8 +91,6 @@ z? For the badly spelled word under the cursor suggest If 'verbose' is non-zero a score will be displayed to indicate the likeliness to the badly spelled word (the higher the score the more different). - The score may be slightly wrong for words with - multi-byte characters. When a word was replaced the redo command "." will repeat the word replacement. This works like "ciw", the good word and . @@ -205,6 +204,25 @@ A word that starts with a digit is always ignored. That includes hex numbers in the form 0xff and 0XFF. +WORD COMBINATIONS + +It is possible to spell-check words that include a space. This is used to +recognize words that are invalid when used by themselves, e.g. for "et al.". +It can also be used to recognize "the the" and highlight it. + +The number of spaces is irrelevant. In most cases a line break may also +appear. However, this makes it difficult to find out where to start checking +for spelling mistakes. When you make a change to one line and only that line +is redrawn Vim won't look in the previous line, thus when "et" is at the end +of the previous line "al." will be flagged as an error. And when you type +"thethe" the highlighting doesn't appear until the first line is redrawn. +Use |CTRL-L| to redraw right away. "[s" will also stop at a word combination +with a line break. + +When encountering a line break Vim skips characters such as '*', '>' and '"', +so that comments in C, shell and Vim code can be spell checked. + + SYNTAX HIGHLIGHTING *spell-syntax* Files that use syntax highlighting can specify where spell checking should be @@ -218,6 +236,15 @@ For the second method adding the @NoSpell cluster will disable spell checking again. This can be used, for example, to add @Spell to the comments of a program, and add @NoSpell for items that shouldn't be checked. + +VIM SCRIPTS + +If you want to write a Vim script that does something with spelling, you may +find these functions useful: + + spellbadword() find badly spelled word at the cursor + spellsuggest() get list of spelling suggestions + ============================================================================== 2. Generating a spell file *spell-mkspell* @@ -228,7 +255,8 @@ You can create a Vim spell file from the .aff and .dic files that Myspell uses. Myspell is used by OpenOffice.org and Mozilla. You should be able to find them here: http://lingucomponent.openoffice.org/spell_dic.html -You can also use a plain word list. +You can also use a plain word list. The results are the same, the choice +depends on what you find. Make sure your current locale is set properly, otherwise Vim doesn't know what characters are upper/lower case letters. If the locale isn't available (e.g., @@ -267,6 +295,10 @@ when using an MS-Windows codepage on Unix) add tables to the .aff file they appear are used. |spell-affix-REP| |spell-affix-SAL| + This command uses a lot of memory, required to find + the optimal word tree (Polish requires a few hundred + Mbyte). The final result will be much smaller. + When the spell file was written all currently used spell files will be reloaded. @@ -520,7 +552,20 @@ rare words. Example: Rare words are highlighted differently from bad words. This is to be used for words that are correct for the language, but are hardly ever used and could be -a typing mistake anyway. +a typing mistake anyway. When the same word is found as good it won't be +highlighted as rare. + + +BAD WORDS + *spell-affix-BAD* +In the affix file a BAD line can be used to define the affix name used for +bad words. Example: + + BAD ! ~ + +This can be used to exclude words that would otherwise be good. For example +"the the". Once a word has been marked as bad it won't be undone by +encountering the same word as good. REPLACEMENTS *spell-affix-REP* diff --git a/runtime/doc/tags b/runtime/doc/tags index ce4807a8e..fe6340eb1 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -731,11 +731,13 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME* 'spell' options.txt /*'spell'* 'spellfile' options.txt /*'spellfile'* 'spelllang' options.txt /*'spelllang'* +'spellsuggest' options.txt /*'spellsuggest'* 'spf' options.txt /*'spf'* 'spl' options.txt /*'spl'* 'splitbelow' options.txt /*'splitbelow'* 'splitright' options.txt /*'splitright'* 'spr' options.txt /*'spr'* +'sps' options.txt /*'sps'* 'sr' options.txt /*'sr'* 'srr' options.txt /*'srr'* 'ss' options.txt /*'ss'* @@ -5130,7 +5132,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* diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt index 6cc15e922..bcb88eb9f 100644 --- a/runtime/doc/various.txt +++ b/runtime/doc/various.txt @@ -1,4 +1,4 @@ -*various.txt* For Vim version 7.0aa. Last change: 2005 May 31 +*various.txt* For Vim version 7.0aa. Last change: 2005 Jun 22 VIM REFERENCE MANUAL by Bram Moolenaar @@ -14,7 +14,8 @@ Various commands *various* 1. Various commands *various-cmds* *CTRL-L* -CTRL-L Clear and redraw the screen (later). +CTRL-L Clear and redraw the screen. The redraw may happen + later, after processing typeahead. *:redr* *:redraw* :redr[aw][!] Redraw the screen right now. When ! is included it is diff --git a/runtime/ftplugin/c.vim b/runtime/ftplugin/c.vim index 39ba8232e..47b2ec6d2 100644 --- a/runtime/ftplugin/c.vim +++ b/runtime/ftplugin/c.vim @@ -1,7 +1,7 @@ " Vim filetype plugin file " Language: C " Maintainer: Bram Moolenaar -" Last Change: 2005 Mar 27 +" Last Change: 2005 Jun 22 " Only do this when not done yet for this buffer if exists("b:did_ftplugin") @@ -12,6 +12,7 @@ endif let b:did_ftplugin = 1 " Using line continuation here. +let s:cpo_save = &cpo set cpo-=C let b:undo_ftplugin = "setl fo< com< | if has('vms') | setl isk< | endif" @@ -48,3 +49,6 @@ if has("gui_win32") && !exists("b:browsefilter") \ "All Files (*.*)\t*.*\n" endif endif + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/runtime/spell/en.latin1.spl b/runtime/spell/en.latin1.spl index ba4990c55..38c4c9cd1 100644 Binary files a/runtime/spell/en.latin1.spl and b/runtime/spell/en.latin1.spl differ diff --git a/src/proto/spell.pro b/src/proto/spell.pro index 15a68a686..2771a902c 100644 --- a/src/proto/spell.pro +++ b/src/proto/spell.pro @@ -1,6 +1,7 @@ /* spell.c */ int spell_check __ARGS((win_T *wp, char_u *ptr, int *attrp)); int spell_move_to __ARGS((int dir, int allwords, int curline)); +void spell_cat_line __ARGS((char_u *buf, char_u *line, int maxlen)); 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)); diff --git a/src/screen.c b/src/screen.c index b1fbedfa2..6fb5931db 100644 --- a/src/screen.c +++ b/src/screen.c @@ -2502,8 +2502,17 @@ win_line(wp, lnum, startrow, endrow) int has_syntax = FALSE; /* this buffer has syntax highl. */ int save_did_emsg; int has_spell = FALSE; /* this buffer has spell checking */ +# define SPWORDLEN 150 + char_u nextline[SPWORDLEN * 2];/* text with start of the next line */ + int nextlinecol; /* column where nextline[] starts */ + int nextline_idx; /* index in nextline[] where next line + starts */ int spell_attr = 0; /* attributes desired by spelling */ int word_end = 0; /* last byte with same spell_attr */ + static linenr_T checked_lnum = 0; /* line number for checked_col */ + static int checked_col = 0; /* column in checked_lnum up to which + * there are no spell errors */ + int cur_checked_col = 0; /* checked column for current line */ #endif int extra_check; /* has syntax or linebreak */ #ifdef FEAT_MBYTE @@ -2609,6 +2618,22 @@ win_line(wp, lnum, startrow, endrow) /* Prepare for spell checking. */ has_spell = TRUE; extra_check = TRUE; + + /* Get the start of the next line, so that words that wrap to the next + * line are found too: "etal.". + * Trick: skip a few chars for C/shell/Vim comments */ + nextline[SPWORDLEN] = NUL; + if (lnum < wp->w_buffer->b_ml.ml_line_count) + { + line = ml_get_buf(wp->w_buffer, lnum + 1, FALSE); + spell_cat_line(nextline + SPWORDLEN, line, SPWORDLEN); + } + + /* When a word wrapped from the previous line the start of the current + * line is valid. */ + if (lnum == checked_lnum) + cur_checked_col = checked_col; + checked_lnum = 0; } #endif @@ -2774,6 +2799,42 @@ win_line(wp, lnum, startrow, endrow) line = ml_get_buf(wp->w_buffer, lnum, FALSE); ptr = line; +#ifdef FEAT_SYN_HL + if (has_spell) + { + /* To be able to spell-check over line boundaries copy the end of the + * current line into nextline[]. Above the start of the next line was + * copied to nextline[SPWORDLEN]. */ + if (nextline[SPWORDLEN] == NUL) + { + /* No next line or it is empty. */ + nextlinecol = MAXCOL; + nextline_idx = 0; + } + else + { + v = STRLEN(line); + if (v < SPWORDLEN) + { + /* Short line, use it completely and append the start of the + * next line. */ + nextlinecol = 0; + mch_memmove(nextline, line, (size_t)v); + mch_memmove(nextline + v, nextline + SPWORDLEN, + STRLEN(nextline + SPWORDLEN) + 1); + nextline_idx = v + 1; + } + else + { + /* Long line, use only the last SPWORDLEN bytes. */ + nextlinecol = v - SPWORDLEN; + mch_memmove(nextline, line + nextlinecol, SPWORDLEN); + nextline_idx = SPWORDLEN + 1; + } + } + } +#endif + /* find start of trailing whitespace */ if (wp->w_p_list && lcs_trail) { @@ -3587,14 +3648,15 @@ win_line(wp, lnum, startrow, endrow) * Only do this when there is no syntax highlighting, the * @Spell cluster is not used or the current syntax item * contains the @Spell cluster. */ - if (has_spell && v >= word_end) + if (has_spell && v >= word_end && v > cur_checked_col) { spell_attr = 0; if (area_attr == 0 && search_attr == 0) char_attr = syntax_attr; if (c != 0 && (!has_syntax || can_spell)) { - char_u *prev_ptr; + char_u *prev_ptr, *p; + int len; # ifdef FEAT_MBYTE if (has_mbyte) { @@ -3604,7 +3666,15 @@ win_line(wp, lnum, startrow, endrow) else # endif prev_ptr = ptr - 1; - word_end = v + spell_check(wp, prev_ptr, &spell_attr); + + /* Use nextline[] if possible, it has the start of the + * next line concatenated. */ + if ((prev_ptr - line) - nextlinecol >= 0) + p = nextline + (prev_ptr - line) - nextlinecol; + else + p = prev_ptr; + len = spell_check(wp, p, &spell_attr); + word_end = v + len; /* In Insert mode only highlight a word that * doesn't touch the cursor. */ @@ -3618,10 +3688,24 @@ win_line(wp, lnum, startrow, endrow) spell_attr = 0; spell_redraw_lnum = lnum; } + + if (spell_attr == 0 && p != prev_ptr + && (p - nextline) + len > nextline_idx) + { + /* Remember that the good word continues at the + * start of the next line. */ + checked_lnum = lnum + 1; + checked_col = (p - nextline) + len - nextline_idx; + } } } if (spell_attr != 0) - char_attr = hl_combine_attr(char_attr, spell_attr); + { + if (area_attr == 0 && search_attr == 0) + char_attr = hl_combine_attr(char_attr, spell_attr); + else + char_attr = hl_combine_attr(spell_attr, char_attr); + } #endif #ifdef FEAT_LINEBREAK /* diff --git a/src/syntax.c b/src/syntax.c index 1d8f41bf3..4fdbbbf6f 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -7591,26 +7591,27 @@ get_attr_entry(table, aep) #if defined(FEAT_SYN_HL) || defined(PROTO) /* - * Combine the spelling attributes with other attributes. "spell_attr" - * overrules "char_attr". + * Combine special attributes (e.g., for spelling) with other attributes + * (e.g., for syntax highlighting). + * "prim_attr" overrules "char_attr". * This creates a new group when required. * Since we expect there to be few spelling mistakes we don't cache the * result. * Return the resulting attributes. */ int -hl_combine_attr(char_attr, spell_attr) +hl_combine_attr(char_attr, prim_attr) int char_attr; - int spell_attr; + int prim_attr; { attrentry_T *char_aep = NULL; attrentry_T *spell_aep; attrentry_T new_en; if (char_attr == 0) - return spell_attr; - if (char_attr <= HL_ALL && spell_attr <= HL_ALL) - return char_attr | spell_attr; + return prim_attr; + if (char_attr <= HL_ALL && prim_attr <= HL_ALL) + return char_attr | prim_attr; #ifdef FEAT_GUI if (gui.in_use) { @@ -7625,11 +7626,11 @@ hl_combine_attr(char_attr, spell_attr) new_en.ae_attr = char_attr; } - if (spell_attr <= HL_ALL) - new_en.ae_attr |= spell_attr; + if (prim_attr <= HL_ALL) + new_en.ae_attr |= prim_attr; else { - spell_aep = syn_gui_attr2entry(spell_attr); + spell_aep = syn_gui_attr2entry(prim_attr); if (spell_aep != NULL) { new_en.ae_attr |= spell_aep->ae_attr; @@ -7664,11 +7665,11 @@ hl_combine_attr(char_attr, spell_attr) new_en.ae_attr = char_attr; } - if (spell_attr <= HL_ALL) - new_en.ae_attr |= spell_attr; + if (prim_attr <= HL_ALL) + new_en.ae_attr |= prim_attr; else { - spell_aep = syn_cterm_attr2entry(spell_attr); + spell_aep = syn_cterm_attr2entry(prim_attr); if (spell_aep != NULL) { new_en.ae_attr |= spell_aep->ae_attr; @@ -7692,11 +7693,11 @@ hl_combine_attr(char_attr, spell_attr) new_en.ae_attr = char_attr; } - if (spell_attr <= HL_ALL) - new_en.ae_attr |= spell_attr; + if (prim_attr <= HL_ALL) + new_en.ae_attr |= prim_attr; else { - spell_aep = syn_cterm_attr2entry(spell_attr); + spell_aep = syn_cterm_attr2entry(prim_attr); if (spell_aep != NULL) { new_en.ae_attr |= spell_aep->ae_attr; -- cgit v1.2.1