aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/spell.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/spell.c')
-rw-r--r--src/nvim/spell.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 85d1e139bf..9fa594bc96 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -62,11 +62,11 @@
// Disadvantage: When "the" is typed as "hte" it sounds quite different ("@"
// vs "ht") and goes down in the list.
// Used when 'spellsuggest' is set to "best".
-#define RESCORE(word_score, sound_score) ((3 * word_score + sound_score) / 4)
+#define RESCORE(word_score, sound_score) ((3 * (word_score) + (sound_score)) / 4)
// Do the opposite: based on a maximum end score and a known sound score,
// compute the maximum word score that can be used.
-#define MAXSCORE(word_score, sound_score) ((4 * word_score - sound_score) / 3)
+#define MAXSCORE(word_score, sound_score) ((4 * (word_score) - (sound_score)) / 3)
#include <assert.h>
#include <inttypes.h>
@@ -94,12 +94,12 @@
#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/hashtab.h"
+#include "nvim/input.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
-#include "nvim/misc1.h"
#include "nvim/normal.h"
#include "nvim/option.h"
#include "nvim/os/input.h"
@@ -122,7 +122,7 @@
#define WF_CAPMASK (WF_ONECAP | WF_ALLCAP | WF_KEEPCAP | WF_FIXCAP)
// Result values. Lower number is accepted over higher one.
-#define SP_BANNED -1
+#define SP_BANNED (-1)
#define SP_RARE 0
#define SP_OK 1
#define SP_LOCAL 2
@@ -176,7 +176,7 @@ typedef struct {
#define SUG(ga, i) (((suggest_T *)(ga).ga_data)[i])
// True if a word appears in the list of banned words.
-#define WAS_BANNED(su, word) (!HASHITEM_EMPTY(hash_find(&su->su_banned, word)))
+#define WAS_BANNED(su, word) (!HASHITEM_EMPTY(hash_find(&(su)->su_banned, word)))
// Number of suggestions kept when cleaning up. We need to keep more than
// what is displayed, because when rescore_suggestions() is called the score
@@ -219,13 +219,13 @@ typedef struct {
#define SCORE_THRES3 100 // word count threshold for COMMON3
// When trying changed soundfold words it becomes slow when trying more than
-// two changes. With less then two changes it's slightly faster but we miss a
+// two changes. With less than two changes it's slightly faster but we miss a
// few good suggestions. In rare cases we need to try three of four changes.
#define SCORE_SFMAX1 200 // maximum score for first try
#define SCORE_SFMAX2 300 // maximum score for second try
#define SCORE_SFMAX3 400 // maximum score for third try
-#define SCORE_BIG SCORE_INS * 3 // big difference
+#define SCORE_BIG (SCORE_INS * 3) // big difference
#define SCORE_MAXMAX 999999 // accept any score
#define SCORE_LIMITMAX 350 // for spell_edit_score_limit()
@@ -1628,7 +1628,7 @@ size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *att
}
// For spell checking: concatenate the start of the following line "line" into
-// "buf", blanking-out special characters. Copy less then "maxlen" bytes.
+// "buf", blanking-out special characters. Copy less than "maxlen" bytes.
// Keep the blanks at the start of the next line, this is used in win_line()
// to skip those bytes if the word was OK.
void spell_cat_line(char_u *buf, char_u *line, int maxlen)
@@ -3066,7 +3066,7 @@ void spell_suggest(int count)
ml_replace(curwin->w_cursor.lnum, p, false);
curwin->w_cursor.col = c;
- changed_bytes(curwin->w_cursor.lnum, c);
+ inserted_bytes(curwin->w_cursor.lnum, c, stp->st_orglen, stp->st_wordlen);
} else {
curwin->w_cursor = prev_cursor;
}
@@ -3690,7 +3690,7 @@ static void suggest_try_change(suginfo_T *su)
// Check the maximum score, if we go over it we won't try this change.
#define TRY_DEEPER(su, stack, depth, add) \
- (stack[depth].ts_score + (add) < su->su_maxscore)
+ ((depth) < MAXWLEN - 1 && (stack)[depth].ts_score + (add) < (su)->su_maxscore)
// Try finding suggestions by adding/removing/swapping letters.
//
@@ -3794,6 +3794,10 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
}
}
+ // The loop may take an indefinite amount of time. Break out after five
+ // sectonds. TODO(vim): add an option for the time limit.
+ proftime_T time_limit = profile_setlimit(5000);
+
// Loop to find all suggestions. At each round we either:
// - For the current state try one operation, advance "ts_curi",
// increase "depth".
@@ -3824,7 +3828,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// At end of a prefix or at start of prefixtree: check for
// following word.
- if (byts[arridx] == 0 || n == (int)STATE_NOPREFIX) {
+ if (depth < MAXWLEN - 1 && (byts[arridx] == 0 || n == STATE_NOPREFIX)) {
// Set su->su_badflags to the caps type at this position.
// Use the caps type until here for the prefix itself.
n = nofold_len(fword, sp->ts_fidx, su->su_badptr);
@@ -4082,7 +4086,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// char, e.g., "thes," -> "these".
p = fword + sp->ts_fidx;
MB_PTR_BACK(fword, p);
- if (!spell_iswordp(p, curwin)) {
+ if (!spell_iswordp(p, curwin) && *preword != NUL) {
p = preword + STRLEN(preword);
MB_PTR_BACK(preword, p);
if (spell_iswordp(p, curwin)) {
@@ -4927,6 +4931,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
if (--breakcheckcount == 0) {
os_breakcheck();
breakcheckcount = 1000;
+ if (profile_passed_limit(time_limit)) {
+ got_int = true;
+ }
}
}
}
@@ -5284,7 +5291,7 @@ static int stp_sal_score(suggest_T *stp, suginfo_T *su, slang_T *slang, char_u *
}
static sftword_T dumsft;
-#define HIKEY2SFT(p) ((sftword_T *)(p - (dumsft.sft_word - (char_u *)&dumsft)))
+#define HIKEY2SFT(p) ((sftword_T *)((p) - (dumsft.sft_word - (char_u *)&dumsft)))
#define HI2SFT(hi) HIKEY2SFT((hi)->hi_key)
// Prepare for calling suggest_try_soundalike().
@@ -6106,7 +6113,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
for (; ((ws = smp[n].sm_lead_w)[0] & 0xff) == (c & 0xff)
&& ws[0] != NUL; ++n) {
// Quickly skip entries that don't match the word. Most
- // entries are less then three chars, optimize for that.
+ // entries are less than three chars, optimize for that.
if (c != ws[0]) {
continue;
}
@@ -7057,7 +7064,7 @@ void spell_dump_compl(char_u *pat, int ic, Direction *dir, int dumpflags_arg)
arridx[depth] = idxs[n];
curi[depth] = 1;
- // Check if this characters matches with the pattern.
+ // Check if this character matches with the pattern.
// If not skip the whole tree below it.
// Always ignore case here, dump_word() will check
// proper case later. This isn't exactly right when