To: vim_dev@googlegroups.com Subject: Patch 8.1.2395 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.2395 Problem: Using old C style comments. Solution: Use // comments where appropriate. Files: src/spell.c, src/spellfile.c, src/syntax.c, src/tag.c, src/term.c, src/terminal.c, src/termlib.c, src/testing.c *** ../vim-8.1.2394/src/spell.c 2019-10-18 20:53:30.697741631 +0200 --- src/spell.c 2019-12-05 21:16:28.390320987 +0100 *************** *** 60,76 **** #if defined(FEAT_SPELL) || defined(PROTO) ! #ifndef UNIX /* it's in os_unix.h for Unix */ ! # include /* for time_t */ #endif ! #define REGION_ALL 0xff /* word valid in all regions */ ! #define VIMSUGMAGIC "VIMsug" /* string at start of Vim .sug file */ #define VIMSUGMAGICL 6 #define VIMSUGVERSION 1 ! /* Result values. Lower number is accepted over higher one. */ #define SP_BANNED -1 #define SP_OK 0 #define SP_RARE 1 --- 60,76 ---- #if defined(FEAT_SPELL) || defined(PROTO) ! #ifndef UNIX // it's in os_unix.h for Unix ! # include // for time_t #endif ! #define REGION_ALL 0xff // word valid in all regions ! #define VIMSUGMAGIC "VIMsug" // string at start of Vim .sug file #define VIMSUGMAGICL 6 #define VIMSUGVERSION 1 ! // Result values. Lower number is accepted over higher one. #define SP_BANNED -1 #define SP_OK 0 #define SP_RARE 1 *************** *** 82,133 **** */ typedef struct matchinf_S { ! langp_T *mi_lp; /* info for language and region */ ! /* pointers to original text to be checked */ ! char_u *mi_word; /* start of word being checked */ ! char_u *mi_end; /* end of matching word so far */ ! char_u *mi_fend; /* next char to be added to mi_fword */ ! char_u *mi_cend; /* char after what was used for ! mi_capflags */ ! ! /* case-folded text */ ! char_u mi_fword[MAXWLEN + 1]; /* mi_word case-folded */ ! int mi_fwordlen; /* nr of valid bytes in mi_fword */ ! ! /* for when checking word after a prefix */ ! int mi_prefarridx; /* index in sl_pidxs with list of ! affixID/condition */ ! int mi_prefcnt; /* number of entries at mi_prefarridx */ ! int mi_prefixlen; /* byte length of prefix */ ! int mi_cprefixlen; /* byte length of prefix in original ! case */ ! ! /* for when checking a compound word */ ! int mi_compoff; /* start of following word offset */ ! char_u mi_compflags[MAXWLEN]; /* flags for compound words used */ ! int mi_complen; /* nr of compound words used */ ! int mi_compextra; /* nr of COMPOUNDROOT words */ ! ! /* others */ ! int mi_result; /* result so far: SP_BAD, SP_OK, etc. */ ! int mi_capflags; /* WF_ONECAP WF_ALLCAP WF_KEEPCAP */ ! win_T *mi_win; /* buffer being checked */ ! ! /* for NOBREAK */ ! int mi_result2; /* "mi_resul" without following word */ ! char_u *mi_end2; /* "mi_end" without following word */ } matchinf_T; static int spell_mb_isword_class(int cl, win_T *wp); ! /* mode values for find_word */ ! #define FIND_FOLDWORD 0 /* find word case-folded */ ! #define FIND_KEEPWORD 1 /* find keep-case word */ ! #define FIND_PREFIX 2 /* find word after prefix */ ! #define FIND_COMPOUND 3 /* find case-folded compound word */ ! #define FIND_KEEPCOMPOUND 4 /* find keep-case compound word */ static void find_word(matchinf_T *mip, int mode); static void find_prefix(matchinf_T *mip, int mode); --- 82,133 ---- */ typedef struct matchinf_S { ! langp_T *mi_lp; // info for language and region ! // pointers to original text to be checked ! char_u *mi_word; // start of word being checked ! char_u *mi_end; // end of matching word so far ! char_u *mi_fend; // next char to be added to mi_fword ! char_u *mi_cend; // char after what was used for ! // mi_capflags ! ! // case-folded text ! char_u mi_fword[MAXWLEN + 1]; // mi_word case-folded ! int mi_fwordlen; // nr of valid bytes in mi_fword ! ! // for when checking word after a prefix ! int mi_prefarridx; // index in sl_pidxs with list of ! // affixID/condition ! int mi_prefcnt; // number of entries at mi_prefarridx ! int mi_prefixlen; // byte length of prefix ! int mi_cprefixlen; // byte length of prefix in original ! // case ! ! // for when checking a compound word ! int mi_compoff; // start of following word offset ! char_u mi_compflags[MAXWLEN]; // flags for compound words used ! int mi_complen; // nr of compound words used ! int mi_compextra; // nr of COMPOUNDROOT words ! ! // others ! int mi_result; // result so far: SP_BAD, SP_OK, etc. ! int mi_capflags; // WF_ONECAP WF_ALLCAP WF_KEEPCAP ! win_T *mi_win; // buffer being checked ! ! // for NOBREAK ! int mi_result2; // "mi_resul" without following word ! char_u *mi_end2; // "mi_end" without following word } matchinf_T; static int spell_mb_isword_class(int cl, win_T *wp); ! // mode values for find_word ! #define FIND_FOLDWORD 0 // find word case-folded ! #define FIND_KEEPWORD 1 // find keep-case word ! #define FIND_PREFIX 2 // find word after prefix ! #define FIND_COMPOUND 3 // find case-folded compound word ! #define FIND_KEEPCOMPOUND 4 // find keep-case compound word static void find_word(matchinf_T *mip, int mode); static void find_prefix(matchinf_T *mip, int mode); *************** *** 160,193 **** */ int spell_check( ! win_T *wp, /* current window */ char_u *ptr, hlf_T *attrp, ! int *capcol, /* column to check for Capital */ ! int docount) /* count good words */ { ! matchinf_T mi; /* Most things are put in "mi" so that it can ! be passed to functions quickly. */ ! int nrlen = 0; /* found a number first */ int c; int wrongcaplen = 0; int lpi; int count_word = docount; ! /* A word never starts at a space or a control character. Return quickly ! * then, skipping over the character. */ if (*ptr <= ' ') return 1; ! /* Return here when loading language files failed. */ if (wp->w_s->b_langp.ga_len == 0) return 1; vim_memset(&mi, 0, sizeof(matchinf_T)); ! /* A number is always OK. Also skip hexadecimal numbers 0xFF99 and ! * 0X99FF. But always do check spelling to find "3GPP" and "11 ! * julifeest". */ if (*ptr >= '0' && *ptr <= '9') { if (*ptr == '0' && (ptr[1] == 'b' || ptr[1] == 'B')) --- 160,193 ---- */ int spell_check( ! win_T *wp, // current window char_u *ptr, hlf_T *attrp, ! int *capcol, // column to check for Capital ! int docount) // count good words { ! matchinf_T mi; // Most things are put in "mi" so that it can ! // be passed to functions quickly. ! int nrlen = 0; // found a number first int c; int wrongcaplen = 0; int lpi; int count_word = docount; ! // A word never starts at a space or a control character. Return quickly ! // then, skipping over the character. if (*ptr <= ' ') return 1; ! // Return here when loading language files failed. if (wp->w_s->b_langp.ga_len == 0) return 1; vim_memset(&mi, 0, sizeof(matchinf_T)); ! // A number is always OK. Also skip hexadecimal numbers 0xFF99 and ! // 0X99FF. But always do check spelling to find "3GPP" and "11 ! // julifeest". if (*ptr >= '0' && *ptr <= '9') { if (*ptr == '0' && (ptr[1] == 'b' || ptr[1] == 'B')) *************** *** 199,205 **** nrlen = (int)(mi.mi_end - ptr); } ! /* Find the normal end of the word (until the next non-word character). */ mi.mi_word = ptr; mi.mi_fend = ptr; if (spell_iswordp(mi.mi_fend, wp)) --- 199,205 ---- nrlen = (int)(mi.mi_end - ptr); } ! // Find the normal end of the word (until the next non-word character). mi.mi_word = ptr; mi.mi_fend = ptr; if (spell_iswordp(mi.mi_fend, wp)) *************** *** 210,216 **** if (capcol != NULL && *capcol == 0 && wp->w_s->b_cap_prog != NULL) { ! /* Check word starting with capital letter. */ c = PTR2CHAR(ptr); if (!SPELL_ISUPPER(c)) wrongcaplen = (int)(mi.mi_fend - ptr); --- 210,216 ---- if (capcol != NULL && *capcol == 0 && wp->w_s->b_cap_prog != NULL) { ! // Check word starting with capital letter. c = PTR2CHAR(ptr); if (!SPELL_ISUPPER(c)) wrongcaplen = (int)(mi.mi_fend - ptr); *************** *** 219,235 **** if (capcol != NULL) *capcol = -1; ! /* We always use the characters up to the next non-word character, ! * also for bad words. */ mi.mi_end = mi.mi_fend; ! /* Check caps type later. */ mi.mi_capflags = 0; mi.mi_cend = NULL; mi.mi_win = wp; ! /* case-fold the word with one non-word character, so that we can check ! * for the word end. */ if (*mi.mi_fend != NUL) MB_PTR_ADV(mi.mi_fend); --- 219,235 ---- if (capcol != NULL) *capcol = -1; ! // We always use the characters up to the next non-word character, ! // also for bad words. mi.mi_end = mi.mi_fend; ! // Check caps type later. mi.mi_capflags = 0; mi.mi_cend = NULL; mi.mi_win = wp; ! // case-fold the word with one non-word character, so that we can check ! // for the word end. if (*mi.mi_fend != NUL) MB_PTR_ADV(mi.mi_fend); *************** *** 237,243 **** MAXWLEN + 1); mi.mi_fwordlen = (int)STRLEN(mi.mi_fword); ! /* The word is bad unless we recognize it. */ mi.mi_result = SP_BAD; mi.mi_result2 = SP_BAD; --- 237,243 ---- MAXWLEN + 1); mi.mi_fwordlen = (int)STRLEN(mi.mi_fword); ! // The word is bad unless we recognize it. mi.mi_result = SP_BAD; mi.mi_result2 = SP_BAD; *************** *** 250,271 **** { mi.mi_lp = LANGP_ENTRY(wp->w_s->b_langp, lpi); ! /* If reloading fails the language is still in the list but everything ! * has been cleared. */ if (mi.mi_lp->lp_slang->sl_fidxs == NULL) continue; ! /* Check for a matching word in case-folded words. */ find_word(&mi, FIND_FOLDWORD); ! /* Check for a matching word in keep-case words. */ find_word(&mi, FIND_KEEPWORD); ! /* Check for matching prefixes. */ find_prefix(&mi, FIND_FOLDWORD); ! /* For a NOBREAK language, may want to use a word without a following ! * word as a backup. */ if (mi.mi_lp->lp_slang->sl_nobreak && mi.mi_result == SP_BAD && mi.mi_result2 != SP_BAD) { --- 250,271 ---- { mi.mi_lp = LANGP_ENTRY(wp->w_s->b_langp, lpi); ! // If reloading fails the language is still in the list but everything ! // has been cleared. if (mi.mi_lp->lp_slang->sl_fidxs == NULL) continue; ! // Check for a matching word in case-folded words. find_word(&mi, FIND_FOLDWORD); ! // Check for a matching word in keep-case words. find_word(&mi, FIND_KEEPWORD); ! // Check for matching prefixes. find_prefix(&mi, FIND_FOLDWORD); ! // For a NOBREAK language, may want to use a word without a following ! // word as a backup. if (mi.mi_lp->lp_slang->sl_nobreak && mi.mi_result == SP_BAD && mi.mi_result2 != SP_BAD) { *************** *** 273,279 **** mi.mi_end = mi.mi_end2; } ! /* Count the word in the first language where it's found to be OK. */ if (count_word && mi.mi_result == SP_OK) { count_common_word(mi.mi_lp->lp_slang, ptr, --- 273,279 ---- mi.mi_end = mi.mi_end2; } ! // Count the word in the first language where it's found to be OK. if (count_word && mi.mi_result == SP_OK) { count_common_word(mi.mi_lp->lp_slang, ptr, *************** *** 284,299 **** if (mi.mi_result != SP_OK) { ! /* If we found a number skip over it. Allows for "42nd". Do flag ! * rare and local words, e.g., "3GPP". */ if (nrlen > 0) { if (mi.mi_result == SP_BAD || mi.mi_result == SP_BANNED) return nrlen; } ! /* When we are at a non-word character there is no error, just ! * skip over the character (try looking for a word after it). */ else if (!spell_iswordp_nmw(ptr, wp)) { if (capcol != NULL && wp->w_s->b_cap_prog != NULL) --- 284,299 ---- if (mi.mi_result != SP_OK) { ! // If we found a number skip over it. Allows for "42nd". Do flag ! // rare and local words, e.g., "3GPP". if (nrlen > 0) { if (mi.mi_result == SP_BAD || mi.mi_result == SP_BANNED) return nrlen; } ! // When we are at a non-word character there is no error, just ! // skip over the character (try looking for a word after it). else if (!spell_iswordp_nmw(ptr, wp)) { if (capcol != NULL && wp->w_s->b_cap_prog != NULL) *************** *** 301,307 **** regmatch_T regmatch; int r; ! /* Check for end of sentence. */ regmatch.regprog = wp->w_s->b_cap_prog; regmatch.rm_ic = FALSE; r = vim_regexec(®match, ptr, 0); --- 301,307 ---- regmatch_T regmatch; int r; ! // Check for end of sentence. regmatch.regprog = wp->w_s->b_cap_prog; regmatch.rm_ic = FALSE; r = vim_regexec(®match, ptr, 0); *************** *** 315,322 **** return 1; } else if (mi.mi_end == ptr) ! /* Always include at least one character. Required for when there ! * is a mixup in "midword". */ MB_PTR_ADV(mi.mi_end); else if (mi.mi_result == SP_BAD && LANGP_ENTRY(wp->w_s->b_langp, 0)->lp_slang->sl_nobreak) --- 315,322 ---- return 1; } else if (mi.mi_end == ptr) ! // Always include at least one character. Required for when there ! // is a mixup in "midword". MB_PTR_ADV(mi.mi_end); else if (mi.mi_result == SP_BAD && LANGP_ENTRY(wp->w_s->b_langp, 0)->lp_slang->sl_nobreak) *************** *** 324,331 **** char_u *p, *fp; int save_result = mi.mi_result; ! /* First language in 'spelllang' is NOBREAK. Find first position ! * at which any word would be valid. */ mi.mi_lp = LANGP_ENTRY(wp->w_s->b_langp, 0); if (mi.mi_lp->lp_slang->sl_fidxs != NULL) { --- 324,331 ---- char_u *p, *fp; int save_result = mi.mi_result; ! // First language in 'spelllang' is NOBREAK. Find first position ! // at which any word would be valid. mi.mi_lp = LANGP_ENTRY(wp->w_s->b_langp, 0); if (mi.mi_lp->lp_slang->sl_fidxs != NULL) { *************** *** 359,365 **** if (wrongcaplen > 0 && (mi.mi_result == SP_OK || mi.mi_result == SP_RARE)) { ! /* Report SpellCap only when the word isn't badly spelled. */ *attrp = HLF_SPC; return wrongcaplen; } --- 359,365 ---- if (wrongcaplen > 0 && (mi.mi_result == SP_OK || mi.mi_result == SP_RARE)) { ! // Report SpellCap only when the word isn't badly spelled. *attrp = HLF_SPC; return wrongcaplen; } *************** *** 380,387 **** find_word(matchinf_T *mip, int mode) { idx_T arridx = 0; ! int endlen[MAXWLEN]; /* length at possible word endings */ ! idx_T endidx[MAXWLEN]; /* possible word endings */ int endidxcnt = 0; int len; int wlen = 0; --- 380,387 ---- find_word(matchinf_T *mip, int mode) { idx_T arridx = 0; ! int endlen[MAXWLEN]; // length at possible word endings ! idx_T endidx[MAXWLEN]; // possible word endings int endidxcnt = 0; int len; int wlen = 0; *************** *** 402,434 **** if (mode == FIND_KEEPWORD || mode == FIND_KEEPCOMPOUND) { ! /* Check for word with matching case in keep-case tree. */ ptr = mip->mi_word; ! flen = 9999; /* no case folding, always enough bytes */ byts = slang->sl_kbyts; idxs = slang->sl_kidxs; if (mode == FIND_KEEPCOMPOUND) ! /* Skip over the previously found word(s). */ wlen += mip->mi_compoff; } else { ! /* Check for case-folded in case-folded tree. */ ptr = mip->mi_fword; ! flen = mip->mi_fwordlen; /* available case-folded bytes */ byts = slang->sl_fbyts; idxs = slang->sl_fidxs; if (mode == FIND_PREFIX) { ! /* Skip over the prefix. */ wlen = mip->mi_prefixlen; flen -= mip->mi_prefixlen; } else if (mode == FIND_COMPOUND) { ! /* Skip over the previously found word(s). */ wlen = mip->mi_compoff; flen -= mip->mi_compoff; } --- 402,434 ---- if (mode == FIND_KEEPWORD || mode == FIND_KEEPCOMPOUND) { ! // Check for word with matching case in keep-case tree. ptr = mip->mi_word; ! flen = 9999; // no case folding, always enough bytes byts = slang->sl_kbyts; idxs = slang->sl_kidxs; if (mode == FIND_KEEPCOMPOUND) ! // Skip over the previously found word(s). wlen += mip->mi_compoff; } else { ! // Check for case-folded in case-folded tree. ptr = mip->mi_fword; ! flen = mip->mi_fwordlen; // available case-folded bytes byts = slang->sl_fbyts; idxs = slang->sl_fidxs; if (mode == FIND_PREFIX) { ! // Skip over the prefix. wlen = mip->mi_prefixlen; flen -= mip->mi_prefixlen; } else if (mode == FIND_COMPOUND) { ! // Skip over the previously found word(s). wlen = mip->mi_compoff; flen -= mip->mi_compoff; } *************** *** 436,442 **** } if (byts == NULL) ! return; /* array is empty */ /* * Repeat advancing in the tree until: --- 436,442 ---- } if (byts == NULL) ! return; // array is empty /* * Repeat advancing in the tree until: *************** *** 451,463 **** len = byts[arridx++]; ! /* If the first possible byte is a zero the word could end here. ! * Remember this index, we first check for the longest word. */ if (byts[arridx] == 0) { if (endidxcnt == MAXWLEN) { ! /* Must be a corrupted spell file. */ emsg(_(e_format)); return; } --- 451,463 ---- len = byts[arridx++]; ! // If the first possible byte is a zero the word could end here. ! // Remember this index, we first check for the longest word. if (byts[arridx] == 0) { if (endidxcnt == MAXWLEN) { ! // Must be a corrupted spell file. emsg(_(e_format)); return; } *************** *** 465,488 **** endidx[endidxcnt++] = arridx++; --len; ! /* Skip over the zeros, there can be several flag/region ! * combinations. */ while (len > 0 && byts[arridx] == 0) { ++arridx; --len; } if (len == 0) ! break; /* no children, word must end here */ } ! /* Stop looking at end of the line. */ if (ptr[wlen] == NUL) break; ! /* Perform a binary search in the list of accepted bytes. */ c = ptr[wlen]; ! if (c == TAB) /* is handled like */ c = ' '; lo = arridx; hi = arridx + len - 1; --- 465,488 ---- endidx[endidxcnt++] = arridx++; --len; ! // Skip over the zeros, there can be several flag/region ! // combinations. while (len > 0 && byts[arridx] == 0) { ++arridx; --len; } if (len == 0) ! break; // no children, word must end here } ! // Stop looking at end of the line. if (ptr[wlen] == NUL) break; ! // Perform a binary search in the list of accepted bytes. c = ptr[wlen]; ! if (c == TAB) // is handled like c = ' '; lo = arridx; hi = arridx + len - 1; *************** *** 500,516 **** } } ! /* Stop if there is no matching byte. */ if (hi < lo || byts[lo] != c) break; ! /* Continue at the child (if there is one). */ arridx = idxs[lo]; ++wlen; --flen; ! /* One space in the good word may stand for several spaces in the ! * checked word. */ if (c == ' ') { for (;;) --- 500,516 ---- } } ! // Stop if there is no matching byte. if (hi < lo || byts[lo] != c) break; ! // Continue at the child (if there is one). arridx = idxs[lo]; ++wlen; --flen; ! // One space in the good word may stand for several spaces in the ! // checked word. if (c == ' ') { for (;;) *************** *** 536,559 **** wlen = endlen[endidxcnt]; if ((*mb_head_off)(ptr, ptr + wlen) > 0) ! continue; /* not at first byte of character */ if (spell_iswordp(ptr + wlen, mip->mi_win)) { if (slang->sl_compprog == NULL && !slang->sl_nobreak) ! continue; /* next char is a word character */ word_ends = FALSE; } else word_ends = TRUE; ! /* The prefix flag is before compound flags. Once a valid prefix flag ! * has been found we try compound flags. */ prefix_found = FALSE; if (mode != FIND_KEEPWORD && has_mbyte) { ! /* Compute byte length in original word, length may change ! * when folding case. This can be slow, take a shortcut when the ! * case-folded word is equal to the keep-case word. */ p = mip->mi_word; if (STRNCMP(ptr, p, wlen) != 0) { --- 536,559 ---- wlen = endlen[endidxcnt]; if ((*mb_head_off)(ptr, ptr + wlen) > 0) ! continue; // not at first byte of character if (spell_iswordp(ptr + wlen, mip->mi_win)) { if (slang->sl_compprog == NULL && !slang->sl_nobreak) ! continue; // next char is a word character word_ends = FALSE; } else word_ends = TRUE; ! // The prefix flag is before compound flags. Once a valid prefix flag ! // has been found we try compound flags. prefix_found = FALSE; if (mode != FIND_KEEPWORD && has_mbyte) { ! // Compute byte length in original word, length may change ! // when folding case. This can be slow, take a shortcut when the ! // case-folded word is equal to the keep-case word. p = mip->mi_word; if (STRNCMP(ptr, p, wlen) != 0) { *************** *** 563,588 **** } } ! /* Check flags and region. For FIND_PREFIX check the condition and ! * prefix ID. ! * Repeat this if there are more flags/region alternatives until there ! * is a match. */ res = SP_BAD; for (len = byts[arridx - 1]; len > 0 && byts[arridx] == 0; --len, ++arridx) { flags = idxs[arridx]; ! /* For the fold-case tree check that the case of the checked word ! * matches with what the word in the tree requires. ! * For keep-case tree the case is always right. For prefixes we ! * don't bother to check. */ if (mode == FIND_FOLDWORD) { if (mip->mi_cend != mip->mi_word + wlen) { ! /* mi_capflags was set for a different word length, need ! * to do it again. */ mip->mi_cend = mip->mi_word + wlen; mip->mi_capflags = captype(mip->mi_word, mip->mi_cend); } --- 563,588 ---- } } ! // Check flags and region. For FIND_PREFIX check the condition and ! // prefix ID. ! // Repeat this if there are more flags/region alternatives until there ! // is a match. res = SP_BAD; for (len = byts[arridx - 1]; len > 0 && byts[arridx] == 0; --len, ++arridx) { flags = idxs[arridx]; ! // For the fold-case tree check that the case of the checked word ! // matches with what the word in the tree requires. ! // For keep-case tree the case is always right. For prefixes we ! // don't bother to check. if (mode == FIND_FOLDWORD) { if (mip->mi_cend != mip->mi_word + wlen) { ! // mi_capflags was set for a different word length, need ! // to do it again. mip->mi_cend = mip->mi_word + wlen; mip->mi_capflags = captype(mip->mi_word, mip->mi_cend); } *************** *** 592,600 **** continue; } ! /* When mode is FIND_PREFIX the word must support the prefix: ! * check the prefix ID and the condition. Do that for the list at ! * mip->mi_prefarridx that find_prefix() filled. */ else if (mode == FIND_PREFIX && !prefix_found) { c = valid_word_prefix(mip->mi_prefcnt, mip->mi_prefarridx, --- 592,600 ---- continue; } ! // When mode is FIND_PREFIX the word must support the prefix: ! // check the prefix ID and the condition. Do that for the list at ! // mip->mi_prefarridx that find_prefix() filled. else if (mode == FIND_PREFIX && !prefix_found) { c = valid_word_prefix(mip->mi_prefcnt, mip->mi_prefarridx, *************** *** 604,610 **** if (c == 0) continue; ! /* Use the WF_RARE flag for a rare prefix. */ if (c & WF_RAREPFX) flags |= WF_RARE; prefix_found = TRUE; --- 604,610 ---- if (c == 0) continue; ! // Use the WF_RARE flag for a rare prefix. if (c & WF_RAREPFX) flags |= WF_RARE; prefix_found = TRUE; *************** *** 615,622 **** if ((mode == FIND_COMPOUND || mode == FIND_KEEPCOMPOUND) && (flags & WF_BANNED) == 0) { ! /* NOBREAK: found a valid following word. That's all we ! * need to know, so return. */ mip->mi_result = SP_OK; break; } --- 615,622 ---- if ((mode == FIND_COMPOUND || mode == FIND_KEEPCOMPOUND) && (flags & WF_BANNED) == 0) { ! // NOBREAK: found a valid following word. That's all we ! // need to know, so return. mip->mi_result = SP_OK; break; } *************** *** 625,669 **** else if ((mode == FIND_COMPOUND || mode == FIND_KEEPCOMPOUND || !word_ends)) { ! /* If there is no compound flag or the word is shorter than ! * COMPOUNDMIN reject it quickly. ! * Makes you wonder why someone puts a compound flag on a word ! * that's too short... Myspell compatibility requires this ! * anyway. */ if (((unsigned)flags >> 24) == 0 || wlen - mip->mi_compoff < slang->sl_compminlen) continue; ! /* For multi-byte chars check character length against ! * COMPOUNDMIN. */ if (has_mbyte && slang->sl_compminlen > 0 && mb_charlen_len(mip->mi_word + mip->mi_compoff, wlen - mip->mi_compoff) < slang->sl_compminlen) continue; ! /* Limit the number of compound words to COMPOUNDWORDMAX if no ! * maximum for syllables is specified. */ if (!word_ends && mip->mi_complen + mip->mi_compextra + 2 > slang->sl_compmax && slang->sl_compsylmax == MAXWLEN) continue; ! /* Don't allow compounding on a side where an affix was added, ! * unless COMPOUNDPERMITFLAG was used. */ if (mip->mi_complen > 0 && (flags & WF_NOCOMPBEF)) continue; if (!word_ends && (flags & WF_NOCOMPAFT)) continue; ! /* Quickly check if compounding is possible with this flag. */ if (!byte_in_str(mip->mi_complen == 0 ? slang->sl_compstartflags : slang->sl_compallflags, ((unsigned)flags >> 24))) continue; ! /* If there is a match with a CHECKCOMPOUNDPATTERN rule ! * discard the compound word. */ if (match_checkcompoundpattern(ptr, wlen, &slang->sl_comppat)) continue; --- 625,669 ---- else if ((mode == FIND_COMPOUND || mode == FIND_KEEPCOMPOUND || !word_ends)) { ! // If there is no compound flag or the word is shorter than ! // COMPOUNDMIN reject it quickly. ! // Makes you wonder why someone puts a compound flag on a word ! // that's too short... Myspell compatibility requires this ! // anyway. if (((unsigned)flags >> 24) == 0 || wlen - mip->mi_compoff < slang->sl_compminlen) continue; ! // For multi-byte chars check character length against ! // COMPOUNDMIN. if (has_mbyte && slang->sl_compminlen > 0 && mb_charlen_len(mip->mi_word + mip->mi_compoff, wlen - mip->mi_compoff) < slang->sl_compminlen) continue; ! // Limit the number of compound words to COMPOUNDWORDMAX if no ! // maximum for syllables is specified. if (!word_ends && mip->mi_complen + mip->mi_compextra + 2 > slang->sl_compmax && slang->sl_compsylmax == MAXWLEN) continue; ! // Don't allow compounding on a side where an affix was added, ! // unless COMPOUNDPERMITFLAG was used. if (mip->mi_complen > 0 && (flags & WF_NOCOMPBEF)) continue; if (!word_ends && (flags & WF_NOCOMPAFT)) continue; ! // Quickly check if compounding is possible with this flag. if (!byte_in_str(mip->mi_complen == 0 ? slang->sl_compstartflags : slang->sl_compallflags, ((unsigned)flags >> 24))) continue; ! // If there is a match with a CHECKCOMPOUNDPATTERN rule ! // discard the compound word. if (match_checkcompoundpattern(ptr, wlen, &slang->sl_comppat)) continue; *************** *** 671,682 **** { int capflags; ! /* Need to check the caps type of the appended compound ! * word. */ if (has_mbyte && STRNCMP(ptr, mip->mi_word, mip->mi_compoff) != 0) { ! /* case folding may have changed the length */ p = mip->mi_word; for (s = ptr; s < ptr + mip->mi_compoff; MB_PTR_ADV(s)) MB_PTR_ADV(p); --- 671,682 ---- { int capflags; ! // Need to check the caps type of the appended compound ! // word. if (has_mbyte && STRNCMP(ptr, mip->mi_word, mip->mi_compoff) != 0) { ! // case folding may have changed the length p = mip->mi_word; for (s = ptr; s < ptr + mip->mi_compoff; MB_PTR_ADV(s)) MB_PTR_ADV(p); *************** *** 690,699 **** if (capflags != WF_ALLCAP) { ! /* When the character before the word is a word ! * character we do not accept a Onecap word. We do ! * accept a no-caps word, even when the dictionary ! * word specifies ONECAP. */ MB_PTR_BACK(mip->mi_word, p); if (spell_iswordp_nmw(p, mip->mi_win) ? capflags == WF_ONECAP --- 690,699 ---- if (capflags != WF_ALLCAP) { ! // When the character before the word is a word ! // character we do not accept a Onecap word. We do ! // accept a no-caps word, even when the dictionary ! // word specifies ONECAP. MB_PTR_BACK(mip->mi_word, p); if (spell_iswordp_nmw(p, mip->mi_win) ? capflags == WF_ONECAP *************** *** 703,711 **** } } ! /* If the word ends the sequence of compound flags of the ! * words must match with one of the COMPOUNDRULE items and ! * the number of syllables must not be too large. */ mip->mi_compflags[mip->mi_complen] = ((unsigned)flags >> 24); mip->mi_compflags[mip->mi_complen + 1] = NUL; if (word_ends) --- 703,711 ---- } } ! // If the word ends the sequence of compound flags of the ! // words must match with one of the COMPOUNDRULE items and ! // the number of syllables must not be too large. mip->mi_compflags[mip->mi_complen] = ((unsigned)flags >> 24); mip->mi_compflags[mip->mi_complen + 1] = NUL; if (word_ends) *************** *** 714,720 **** if (slang->sl_compsylmax < MAXWLEN) { ! /* "fword" is only needed for checking syllables. */ if (ptr == mip->mi_word) (void)spell_casefold(ptr, wlen, fword, MAXWLEN); else --- 714,720 ---- if (slang->sl_compsylmax < MAXWLEN) { ! // "fword" is only needed for checking syllables. if (ptr == mip->mi_word) (void)spell_casefold(ptr, wlen, fword, MAXWLEN); else *************** *** 725,736 **** } else if (slang->sl_comprules != NULL && !match_compoundrule(slang, mip->mi_compflags)) ! /* The compound flags collected so far do not match any ! * COMPOUNDRULE, discard the compounded word. */ continue; } ! /* Check NEEDCOMPOUND: can't use word without compounding. */ else if (flags & WF_NEEDCOMP) continue; --- 725,736 ---- } else if (slang->sl_comprules != NULL && !match_compoundrule(slang, mip->mi_compflags)) ! // The compound flags collected so far do not match any ! // COMPOUNDRULE, discard the compounded word. continue; } ! // Check NEEDCOMPOUND: can't use word without compounding. else if (flags & WF_NEEDCOMP) continue; *************** *** 743,764 **** langp_T *save_lp = mip->mi_lp; int lpi; ! /* Check that a valid word follows. If there is one and we ! * are compounding, it will set "mi_result", thus we are ! * always finished here. For NOBREAK we only check that a ! * valid word follows. ! * Recursive! */ if (slang->sl_nobreak) mip->mi_result = SP_BAD; ! /* Find following word in case-folded tree. */ mip->mi_compoff = endlen[endidxcnt]; if (has_mbyte && mode == FIND_KEEPWORD) { ! /* Compute byte length in case-folded word from "wlen": ! * byte length in keep-case word. Length may change when ! * folding case. This can be slow, take a shortcut when ! * the case-folded word is equal to the keep-case word. */ p = mip->mi_fword; if (STRNCMP(ptr, p, wlen) != 0) { --- 743,764 ---- langp_T *save_lp = mip->mi_lp; int lpi; ! // Check that a valid word follows. If there is one and we ! // are compounding, it will set "mi_result", thus we are ! // always finished here. For NOBREAK we only check that a ! // valid word follows. ! // Recursive! if (slang->sl_nobreak) mip->mi_result = SP_BAD; ! // Find following word in case-folded tree. mip->mi_compoff = endlen[endidxcnt]; if (has_mbyte && mode == FIND_KEEPWORD) { ! // Compute byte length in case-folded word from "wlen": ! // byte length in keep-case word. Length may change when ! // folding case. This can be slow, take a shortcut when ! // the case-folded word is equal to the keep-case word. p = mip->mi_fword; if (STRNCMP(ptr, p, wlen) != 0) { *************** *** 767,781 **** mip->mi_compoff = (int)(p - mip->mi_fword); } } ! #if 0 /* Disabled, see below */ c = mip->mi_compoff; #endif ++mip->mi_complen; if (flags & WF_COMPROOT) ++mip->mi_compextra; ! /* For NOBREAK we need to try all NOBREAK languages, at least ! * to find the ".add" file(s). */ for (lpi = 0; lpi < mip->mi_win->w_s->b_langp.ga_len; ++lpi) { if (slang->sl_nobreak) --- 767,781 ---- mip->mi_compoff = (int)(p - mip->mi_fword); } } ! #if 0 // Disabled, see below c = mip->mi_compoff; #endif ++mip->mi_complen; if (flags & WF_COMPROOT) ++mip->mi_compextra; ! // For NOBREAK we need to try all NOBREAK languages, at least ! // to find the ".add" file(s). for (lpi = 0; lpi < mip->mi_win->w_s->b_langp.ga_len; ++lpi) { if (slang->sl_nobreak) *************** *** 788,808 **** find_word(mip, FIND_COMPOUND); ! /* When NOBREAK any word that matches is OK. Otherwise we ! * need to find the longest match, thus try with keep-case ! * and prefix too. */ if (!slang->sl_nobreak || mip->mi_result == SP_BAD) { ! /* Find following word in keep-case tree. */ mip->mi_compoff = wlen; find_word(mip, FIND_KEEPCOMPOUND); ! #if 0 /* Disabled, a prefix must not appear halfway a compound word, ! unless the COMPOUNDPERMITFLAG is used and then it can't be a ! postponed prefix. */ if (!slang->sl_nobreak || mip->mi_result == SP_BAD) { ! /* Check for following word with prefix. */ mip->mi_compoff = c; find_prefix(mip, FIND_COMPOUND); } --- 788,808 ---- find_word(mip, FIND_COMPOUND); ! // When NOBREAK any word that matches is OK. Otherwise we ! // need to find the longest match, thus try with keep-case ! // and prefix too. if (!slang->sl_nobreak || mip->mi_result == SP_BAD) { ! // Find following word in keep-case tree. mip->mi_compoff = wlen; find_word(mip, FIND_KEEPCOMPOUND); ! #if 0 // Disabled, a prefix must not appear halfway a compound word, ! // unless the COMPOUNDPERMITFLAG is used and then it can't be a ! // postponed prefix. if (!slang->sl_nobreak || mip->mi_result == SP_BAD) { ! // Check for following word with prefix. mip->mi_compoff = c; find_prefix(mip, FIND_COMPOUND); } *************** *** 835,841 **** res = SP_BANNED; else if (flags & WF_REGION) { ! /* Check region. */ if ((mip->mi_lp->lp_region & (flags >> 16)) != 0) res = SP_OK; else --- 835,841 ---- res = SP_BANNED; else if (flags & WF_REGION) { ! // Check region. if ((mip->mi_lp->lp_region & (flags >> 16)) != 0) res = SP_OK; else *************** *** 846,854 **** else res = SP_OK; ! /* Always use the longest match and the best result. For NOBREAK ! * we separately keep the longest match without a following good ! * word as a fall-back. */ if (nobreak_result == SP_BAD) { if (mip->mi_result2 > res) --- 846,854 ---- else res = SP_OK; ! // Always use the longest match and the best result. For NOBREAK ! // we separately keep the longest match without a following good ! // word as a fall-back. if (nobreak_result == SP_BAD) { if (mip->mi_result2 > res) *************** *** 888,894 **** match_checkcompoundpattern( char_u *ptr, int wlen, ! garray_T *gap) /* &sl_comppat */ { int i; char_u *p; --- 888,894 ---- match_checkcompoundpattern( char_u *ptr, int wlen, ! garray_T *gap) // &sl_comppat { int i; char_u *p; *************** *** 899,906 **** p = ((char_u **)gap->ga_data)[i + 1]; if (STRNCMP(ptr + wlen, p, STRLEN(p)) == 0) { ! /* Second part matches at start of following compound word, now ! * check if first part matches at end of previous word. */ p = ((char_u **)gap->ga_data)[i]; len = (int)STRLEN(p); if (len <= wlen && STRNCMP(ptr + wlen - len, p, len) == 0) --- 899,906 ---- p = ((char_u **)gap->ga_data)[i + 1]; if (STRNCMP(ptr + wlen, p, STRLEN(p)) == 0) { ! // Second part matches at start of following compound word, now ! // check if first part matches at end of previous word. p = ((char_u **)gap->ga_data)[i]; len = (int)STRLEN(p); if (len <= wlen && STRNCMP(ptr + wlen - len, p, len) == 0) *************** *** 925,931 **** return FALSE; if (enc_utf8) { ! /* Need to convert the single byte flags to utf8 characters. */ p = uflags; for (i = 0; flags[i] != NUL; ++i) p += utf_char2bytes(flags[i], p); --- 925,931 ---- return FALSE; if (enc_utf8) { ! // Need to convert the single byte flags to utf8 characters. p = uflags; for (i = 0; flags[i] != NUL; ++i) p += utf_char2bytes(flags[i], p); *************** *** 937,945 **** if (!vim_regexec_prog(&slang->sl_compprog, FALSE, p, 0)) return FALSE; ! /* Count the number of syllables. This may be slow, do it last. If there ! * are too many syllables AND the number of compound words is above ! * COMPOUNDWORDMAX then compounding is not allowed. */ if (slang->sl_compsylmax < MAXWLEN && count_syllables(slang, word) > slang->sl_compsylmax) return (int)STRLEN(flags) < slang->sl_compmax; --- 937,945 ---- if (!vim_regexec_prog(&slang->sl_compprog, FALSE, p, 0)) return FALSE; ! // Count the number of syllables. This may be slow, do it last. If there ! // are too many syllables AND the number of compound words is above ! // COMPOUNDWORDMAX then compounding is not allowed. if (slang->sl_compsylmax < MAXWLEN && count_syllables(slang, word) > slang->sl_compsylmax) return (int)STRLEN(flags) < slang->sl_compmax; *************** *** 959,1002 **** int i; int c; ! /* loop over all the COMPOUNDRULE entries */ for (p = slang->sl_comprules; *p != NUL; ++p) { ! /* loop over the flags in the compound word we have made, match ! * them against the current rule entry */ for (i = 0; ; ++i) { c = compflags[i]; if (c == NUL) ! /* found a rule that matches for the flags we have so far */ return TRUE; if (*p == '/' || *p == NUL) ! break; /* end of rule, it's too short */ if (*p == '[') { int match = FALSE; ! /* compare against all the flags in [] */ ++p; while (*p != ']' && *p != NUL) if (*p++ == c) match = TRUE; if (!match) ! break; /* none matches */ } else if (*p != c) ! break; /* flag of word doesn't match flag in pattern */ ++p; } ! /* Skip to the next "/", where the next pattern starts. */ p = vim_strchr(p, '/'); if (p == NULL) break; } ! /* Checked all the rules and none of them match the flags, so there ! * can't possibly be a compound starting with these flags. */ return FALSE; } --- 959,1002 ---- int i; int c; ! // loop over all the COMPOUNDRULE entries for (p = slang->sl_comprules; *p != NUL; ++p) { ! // loop over the flags in the compound word we have made, match ! // them against the current rule entry for (i = 0; ; ++i) { c = compflags[i]; if (c == NUL) ! // found a rule that matches for the flags we have so far return TRUE; if (*p == '/' || *p == NUL) ! break; // end of rule, it's too short if (*p == '[') { int match = FALSE; ! // compare against all the flags in [] ++p; while (*p != ']' && *p != NUL) if (*p++ == c) match = TRUE; if (!match) ! break; // none matches } else if (*p != c) ! break; // flag of word doesn't match flag in pattern ++p; } ! // Skip to the next "/", where the next pattern starts. p = vim_strchr(p, '/'); if (p == NULL) break; } ! // Checked all the rules and none of them match the flags, so there ! // can't possibly be a compound starting with these flags. return FALSE; } *************** *** 1007,1018 **** */ int valid_word_prefix( ! int totprefcnt, /* nr of prefix IDs */ ! int arridx, /* idx in sl_pidxs[] */ int flags, char_u *word, slang_T *slang, ! int cond_req) /* only use prefixes with a condition */ { int prefcnt; int pidx; --- 1007,1018 ---- */ int valid_word_prefix( ! int totprefcnt, // nr of prefix IDs ! int arridx, // idx in sl_pidxs[] int flags, char_u *word, slang_T *slang, ! int cond_req) // only use prefixes with a condition { int prefcnt; int pidx; *************** *** 1024,1040 **** { pidx = slang->sl_pidxs[arridx + prefcnt]; ! /* Check the prefix ID. */ if (prefid != (pidx & 0xff)) continue; ! /* Check if the prefix doesn't combine and the word already has a ! * suffix. */ if ((flags & WF_HAS_AFF) && (pidx & WF_PFX_NC)) continue; ! /* Check the condition, if there is one. The condition index is ! * stored in the two bytes above the prefix ID byte. */ rp = &slang->sl_prefprog[((unsigned)pidx >> 8) & 0xffff]; if (*rp != NULL) { --- 1024,1040 ---- { pidx = slang->sl_pidxs[arridx + prefcnt]; ! // Check the prefix ID. if (prefid != (pidx & 0xff)) continue; ! // Check if the prefix doesn't combine and the word already has a ! // suffix. if ((flags & WF_HAS_AFF) && (pidx & WF_PFX_NC)) continue; ! // Check the condition, if there is one. The condition index is ! // stored in the two bytes above the prefix ID byte. rp = &slang->sl_prefprog[((unsigned)pidx >> 8) & 0xffff]; if (*rp != NULL) { *************** *** 1044,1050 **** else if (cond_req) continue; ! /* It's a match! Return the WF_ flags. */ return pidx; } return 0; --- 1044,1050 ---- else if (cond_req) continue; ! // It's a match! Return the WF_ flags. return pidx; } return 0; *************** *** 1075,1089 **** byts = slang->sl_pbyts; if (byts == NULL) ! return; /* array is empty */ ! /* We use the case-folded word here, since prefixes are always ! * case-folded. */ ptr = mip->mi_fword; ! flen = mip->mi_fwordlen; /* available case-folded bytes */ if (mode == FIND_COMPOUND) { ! /* Skip over the previously found word(s). */ ptr += mip->mi_compoff; flen -= mip->mi_compoff; } --- 1075,1089 ---- byts = slang->sl_pbyts; if (byts == NULL) ! return; // array is empty ! // We use the case-folded word here, since prefixes are always ! // case-folded. ptr = mip->mi_fword; ! flen = mip->mi_fwordlen; // available case-folded bytes if (mode == FIND_COMPOUND) { ! // Skip over the previously found word(s). ptr += mip->mi_compoff; flen -= mip->mi_compoff; } *************** *** 1102,1115 **** len = byts[arridx++]; ! /* If the first possible byte is a zero the prefix could end here. ! * Check if the following word matches and supports the prefix. */ if (byts[arridx] == 0) { ! /* There can be several prefixes with different conditions. We ! * try them all, since we don't know which one will give the ! * longest match. The word is the same each time, pass the list ! * of possible prefixes to find_word(). */ mip->mi_prefarridx = arridx; mip->mi_prefcnt = len; while (len > 0 && byts[arridx] == 0) --- 1102,1115 ---- len = byts[arridx++]; ! // If the first possible byte is a zero the prefix could end here. ! // Check if the following word matches and supports the prefix. if (byts[arridx] == 0) { ! // There can be several prefixes with different conditions. We ! // try them all, since we don't know which one will give the ! // longest match. The word is the same each time, pass the list ! // of possible prefixes to find_word(). mip->mi_prefarridx = arridx; mip->mi_prefcnt = len; while (len > 0 && byts[arridx] == 0) *************** *** 1119,1133 **** } mip->mi_prefcnt -= len; ! /* Find the word that comes after the prefix. */ mip->mi_prefixlen = wlen; if (mode == FIND_COMPOUND) ! /* Skip over the previously found word(s). */ mip->mi_prefixlen += mip->mi_compoff; if (has_mbyte) { ! /* Case-folded length may differ from original length. */ mip->mi_cprefixlen = nofold_len(mip->mi_fword, mip->mi_prefixlen, mip->mi_word); } --- 1119,1133 ---- } mip->mi_prefcnt -= len; ! // Find the word that comes after the prefix. mip->mi_prefixlen = wlen; if (mode == FIND_COMPOUND) ! // Skip over the previously found word(s). mip->mi_prefixlen += mip->mi_compoff; if (has_mbyte) { ! // Case-folded length may differ from original length. mip->mi_cprefixlen = nofold_len(mip->mi_fword, mip->mi_prefixlen, mip->mi_word); } *************** *** 1137,1150 **** if (len == 0) ! break; /* no children, word must end here */ } ! /* Stop looking at end of the line. */ if (ptr[wlen] == NUL) break; ! /* Perform a binary search in the list of accepted bytes. */ c = ptr[wlen]; lo = arridx; hi = arridx + len - 1; --- 1137,1150 ---- if (len == 0) ! break; // no children, word must end here } ! // Stop looking at end of the line. if (ptr[wlen] == NUL) break; ! // Perform a binary search in the list of accepted bytes. c = ptr[wlen]; lo = arridx; hi = arridx + len - 1; *************** *** 1162,1172 **** } } ! /* Stop if there is no matching byte. */ if (hi < lo || byts[lo] != c) break; ! /* Continue at the child (if there is one). */ arridx = idxs[lo]; ++wlen; --flen; --- 1162,1172 ---- } } ! // Stop if there is no matching byte. if (hi < lo || byts[lo] != c) break; ! // Continue at the child (if there is one). arridx = idxs[lo]; ++wlen; --flen; *************** *** 1189,1195 **** MB_PTR_ADV(mip->mi_fend); while (*mip->mi_fend != NUL && spell_iswordp(mip->mi_fend, mip->mi_win)); ! /* Include the non-word character so that we can check for the word end. */ if (*mip->mi_fend != NUL) MB_PTR_ADV(mip->mi_fend); --- 1189,1195 ---- MB_PTR_ADV(mip->mi_fend); while (*mip->mi_fend != NUL && spell_iswordp(mip->mi_fend, mip->mi_win)); ! // Include the non-word character so that we can check for the word end. if (*mip->mi_fend != NUL) MB_PTR_ADV(mip->mi_fend); *************** *** 1207,1214 **** */ int spell_valid_case( ! int wordflags, /* flags for the checked word. */ ! int treeflags) /* flags for the word in the spell tree */ { return ((wordflags == WF_ALLCAP && (treeflags & WF_FIXCAP) == 0) || ((treeflags & (WF_ALLCAP | WF_KEEPCAP)) == 0 --- 1207,1214 ---- */ int spell_valid_case( ! int wordflags, // flags for the checked word. ! int treeflags) // flags for the word in the spell tree { return ((wordflags == WF_ALLCAP && (treeflags & WF_FIXCAP) == 0) || ((treeflags & (WF_ALLCAP | WF_KEEPCAP)) == 0 *************** *** 1242,1252 **** int spell_move_to( win_T *wp, ! int dir, /* FORWARD or BACKWARD */ ! int allwords, /* TRUE for "[s"/"]s", FALSE for "[S"/"]S" */ int curline, ! hlf_T *attrp) /* return: attributes of bad word or NULL ! (only when "dir" is FORWARD) */ { linenr_T lnum; pos_T found_pos; --- 1242,1252 ---- int spell_move_to( win_T *wp, ! int dir, // FORWARD or BACKWARD ! int allwords, // TRUE for "[s"/"]s", FALSE for "[S"/"]S" int curline, ! hlf_T *attrp) // return: attributes of bad word or NULL ! // (only when "dir" is FORWARD) { linenr_T lnum; pos_T found_pos; *************** *** 1299,1325 **** break; } ! /* In first line check first word for Capital. */ if (lnum == 1) capcol = 0; ! /* For checking first word with a capital skip white space. */ if (capcol == 0) capcol = getwhitecols(line); else if (curline && wp == curwin) { ! /* For spellbadword(): check if first word needs a capital. */ col = getwhitecols(line); if (check_need_cap(lnum, col)) capcol = col; ! /* Need to get the line again, may have looked at the previous ! * one. */ line = ml_get_buf(wp->w_buffer, lnum, FALSE); } ! /* Copy the line into "buf" and append the start of the next line if ! * possible. */ STRCPY(buf, line); if (lnum < wp->w_buffer->b_ml.ml_line_count) spell_cat_line(buf + STRLEN(buf), --- 1299,1325 ---- break; } ! // In first line check first word for Capital. if (lnum == 1) capcol = 0; ! // For checking first word with a capital skip white space. if (capcol == 0) capcol = getwhitecols(line); else if (curline && wp == curwin) { ! // For spellbadword(): check if first word needs a capital. col = getwhitecols(line); if (check_need_cap(lnum, col)) capcol = col; ! // Need to get the line again, may have looked at the previous ! // one. line = ml_get_buf(wp->w_buffer, lnum, FALSE); } ! // Copy the line into "buf" and append the start of the next line if ! // possible. STRCPY(buf, line); if (lnum < wp->w_buffer->b_ml.ml_line_count) spell_cat_line(buf + STRLEN(buf), *************** *** 1329,1353 **** endp = buf + len; while (p < endp) { ! /* When searching backward don't search after the cursor. Unless ! * we wrapped around the end of the buffer. */ if (dir == BACKWARD && lnum == wp->w_cursor.lnum && !wrapped && (colnr_T)(p - buf) >= wp->w_cursor.col) break; ! /* start of word */ attr = HLF_COUNT; len = spell_check(wp, p, &attr, &capcol, FALSE); if (attr != HLF_COUNT) { ! /* We found a bad word. Check the attribute. */ if (allwords || attr == HLF_SPB) { ! /* When searching forward only accept a bad word after ! * the cursor. */ if (dir == BACKWARD || lnum != wp->w_cursor.lnum || (lnum == wp->w_cursor.lnum --- 1329,1353 ---- endp = buf + len; while (p < endp) { ! // When searching backward don't search after the cursor. Unless ! // we wrapped around the end of the buffer. if (dir == BACKWARD && lnum == wp->w_cursor.lnum && !wrapped && (colnr_T)(p - buf) >= wp->w_cursor.col) break; ! // start of word attr = HLF_COUNT; len = spell_check(wp, p, &attr, &capcol, FALSE); if (attr != HLF_COUNT) { ! // We found a bad word. Check the attribute. if (allwords || attr == HLF_SPB) { ! // When searching forward only accept a bad word after ! // the cursor. if (dir == BACKWARD || lnum != wp->w_cursor.lnum || (lnum == wp->w_cursor.lnum *************** *** 1377,1383 **** found_pos.coladd = 0; if (dir == FORWARD) { ! /* No need to search further. */ wp->w_cursor = found_pos; vim_free(buf); if (attrp != NULL) --- 1377,1383 ---- found_pos.coladd = 0; if (dir == FORWARD) { ! // No need to search further. wp->w_cursor = found_pos; vim_free(buf); if (attrp != NULL) *************** *** 1385,1392 **** return len; } else if (curline) ! /* Insert mode completion: put cursor after ! * the bad word. */ found_pos.col += len; found_len = len; } --- 1385,1392 ---- return len; } else if (curline) ! // Insert mode completion: put cursor after ! // the bad word. found_pos.col += len; found_len = len; } *************** *** 1396,1433 **** } } ! /* advance to character after the word */ p += len; capcol -= len; } if (dir == BACKWARD && found_pos.lnum != 0) { ! /* Use the last match in the line (before the cursor). */ wp->w_cursor = found_pos; vim_free(buf); return found_len; } if (curline) ! break; /* only check cursor line */ ! /* If we are back at the starting line and searched it again there ! * is no match, give up. */ if (lnum == wp->w_cursor.lnum && wrapped) break; ! /* Advance to next line. */ if (dir == BACKWARD) { if (lnum > 1) --lnum; else if (!p_ws) ! break; /* at first line and 'nowrapscan' */ else { ! /* Wrap around to the end of the buffer. May search the ! * starting line again and accept the last match. */ lnum = wp->w_buffer->b_ml.ml_line_count; wrapped = TRUE; if (!shortmess(SHM_SEARCH)) --- 1396,1433 ---- } } ! // advance to character after the word p += len; capcol -= len; } if (dir == BACKWARD && found_pos.lnum != 0) { ! // Use the last match in the line (before the cursor). wp->w_cursor = found_pos; vim_free(buf); return found_len; } if (curline) ! break; // only check cursor line ! // If we are back at the starting line and searched it again there ! // is no match, give up. if (lnum == wp->w_cursor.lnum && wrapped) break; ! // Advance to next line. if (dir == BACKWARD) { if (lnum > 1) --lnum; else if (!p_ws) ! break; // at first line and 'nowrapscan' else { ! // Wrap around to the end of the buffer. May search the ! // starting line again and accept the last match. lnum = wp->w_buffer->b_ml.ml_line_count; wrapped = TRUE; if (!shortmess(SHM_SEARCH)) *************** *** 1440,1472 **** if (lnum < wp->w_buffer->b_ml.ml_line_count) ++lnum; else if (!p_ws) ! break; /* at first line and 'nowrapscan' */ else { ! /* Wrap around to the start of the buffer. May search the ! * starting line again and accept the first match. */ lnum = 1; wrapped = TRUE; if (!shortmess(SHM_SEARCH)) give_warning((char_u *)_(bot_top_msg), TRUE); } ! /* If we are back at the starting line and there is no match then ! * give up. */ if (lnum == wp->w_cursor.lnum && !found_one) break; ! /* Skip the characters at the start of the next line that were ! * included in a match crossing line boundaries. */ if (attr == HLF_COUNT) skip = (int)(p - endp); else skip = 0; ! /* Capcol skips over the inserted space. */ --capcol; ! /* But after empty line check first word in next line */ if (*skipwhite(line) == NUL) capcol = 0; } --- 1440,1472 ---- if (lnum < wp->w_buffer->b_ml.ml_line_count) ++lnum; else if (!p_ws) ! break; // at first line and 'nowrapscan' else { ! // Wrap around to the start of the buffer. May search the ! // starting line again and accept the first match. lnum = 1; wrapped = TRUE; if (!shortmess(SHM_SEARCH)) give_warning((char_u *)_(bot_top_msg), TRUE); } ! // If we are back at the starting line and there is no match then ! // give up. if (lnum == wp->w_cursor.lnum && !found_one) break; ! // Skip the characters at the start of the next line that were ! // included in a match crossing line boundaries. if (attr == HLF_COUNT) skip = (int)(p - endp); else skip = 0; ! // Capcol skips over the inserted space. --capcol; ! // But after empty line check first word in next line if (*skipwhite(line) == NUL) capcol = 0; } *************** *** 1496,1503 **** if (*p != NUL) { ! /* Only worth concatenating if there is something else than spaces to ! * concatenate. */ n = (int)(p - line) + 1; if (n < maxlen - 1) { --- 1496,1503 ---- if (*p != NUL) { ! // Only worth concatenating if there is something else than spaces to ! // concatenate. n = (int)(p - line) + 1; if (n < maxlen - 1) { *************** *** 1512,1520 **** */ typedef struct spelload_S { ! char_u sl_lang[MAXWLEN + 1]; /* language name */ ! slang_T *sl_slang; /* resulting slang_T struct */ ! int sl_nobreak; /* NOBREAK language found */ } spelload_T; /* --- 1512,1520 ---- */ typedef struct spelload_S { ! char_u sl_lang[MAXWLEN + 1]; // language name ! slang_T *sl_slang; // resulting slang_T struct ! int sl_nobreak; // NOBREAK language found } spelload_T; /* *************** *** 1529,1542 **** spelload_T sl; int round; ! /* Copy the language name to pass it to spell_load_cb() as a cookie. ! * It's truncated when an error is detected. */ STRCPY(sl.sl_lang, lang); sl.sl_slang = NULL; sl.sl_nobreak = FALSE; ! /* We may retry when no spell file is found for the language, an ! * autocommand may load it then. */ for (round = 1; round <= 2; ++round) { /* --- 1529,1542 ---- spelload_T sl; int round; ! // Copy the language name to pass it to spell_load_cb() as a cookie. ! // It's truncated when an error is detected. STRCPY(sl.sl_lang, lang); sl.sl_slang = NULL; sl.sl_nobreak = FALSE; ! // We may retry when no spell file is found for the language, an ! // autocommand may load it then. for (round = 1; round <= 2; ++round) { /* *************** *** 1553,1559 **** if (r == FAIL && *sl.sl_lang != NUL) { ! /* Try loading the ASCII version. */ vim_snprintf((char *)fname_enc, sizeof(fname_enc) - 5, #ifdef VMS "spell/%s_ascii.spl", --- 1553,1559 ---- if (r == FAIL && *sl.sl_lang != NUL) { ! // Try loading the ASCII version. vim_snprintf((char *)fname_enc, sizeof(fname_enc) - 5, #ifdef VMS "spell/%s_ascii.spl", *************** *** 1584,1590 **** } else if (sl.sl_slang != NULL) { ! /* At least one file was loaded, now load ALL the additions. */ STRCPY(fname_enc + STRLEN(fname_enc) - 3, "add.spl"); do_in_runtimepath(fname_enc, DIP_ALL, spell_load_cb, &sl); } --- 1584,1590 ---- } else if (sl.sl_slang != NULL) { ! // At least one file was loaded, now load ALL the additions. STRCPY(fname_enc + STRLEN(fname_enc) - 3, "add.spl"); do_in_runtimepath(fname_enc, DIP_ALL, spell_load_cb, &sl); } *************** *** 1685,1703 **** gap = &lp->sl_sal; if (lp->sl_sofo) { ! /* "ga_len" is set to 1 without adding an item for latin1 */ if (gap->ga_data != NULL) ! /* SOFOFROM and SOFOTO items: free lists of wide characters. */ for (i = 0; i < gap->ga_len; ++i) vim_free(((int **)gap->ga_data)[i]); } else ! /* SAL items: free salitem_T items */ while (gap->ga_len > 0) { smp = &((salitem_T *)gap->ga_data)[--gap->ga_len]; vim_free(smp->sm_lead); ! /* Don't free sm_oneof and sm_rules, they point into sm_lead. */ vim_free(smp->sm_to); vim_free(smp->sm_lead_w); vim_free(smp->sm_oneof_w); --- 1685,1703 ---- gap = &lp->sl_sal; if (lp->sl_sofo) { ! // "ga_len" is set to 1 without adding an item for latin1 if (gap->ga_data != NULL) ! // SOFOFROM and SOFOTO items: free lists of wide characters. for (i = 0; i < gap->ga_len; ++i) vim_free(((int **)gap->ga_data)[i]); } else ! // SAL items: free salitem_T items while (gap->ga_len > 0) { smp = &((salitem_T *)gap->ga_data)[--gap->ga_len]; vim_free(smp->sm_lead); ! // Don't free sm_oneof and sm_rules, they point into sm_lead. vim_free(smp->sm_to); vim_free(smp->sm_lead_w); vim_free(smp->sm_oneof_w); *************** *** 1730,1736 **** hash_clear_all(&lp->sl_map_hash, 0); ! /* Clear info from .sug file. */ slang_clear_sug(lp); lp->sl_compmax = MAXWLEN; --- 1730,1736 ---- hash_clear_all(&lp->sl_map_hash, 0); ! // Clear info from .sug file. slang_clear_sug(lp); lp->sl_compmax = MAXWLEN; *************** *** 1766,1773 **** slang = spell_load_file(fname, slp->sl_lang, NULL, FALSE); if (slang != NULL) { ! /* When a previously loaded file has NOBREAK also use it for the ! * ".add" files. */ if (slp->sl_nobreak && slang->sl_add) slang->sl_nobreak = TRUE; else if (slang->sl_nobreak) --- 1766,1773 ---- slang = spell_load_file(fname, slp->sl_lang, NULL, FALSE); if (slang != NULL) { ! // When a previously loaded file has NOBREAK also use it for the ! // ".add" files. if (slp->sl_nobreak && slang->sl_add) slang->sl_nobreak = TRUE; else if (slang->sl_nobreak) *************** *** 1786,1793 **** count_common_word( slang_T *lp, char_u *word, ! int len, /* word length, -1 for upto NUL */ ! int count) /* 1 to count once, 10 to init */ { hash_T hash; hashitem_T *hi; --- 1786,1793 ---- count_common_word( slang_T *lp, char_u *word, ! int len, // word length, -1 for upto NUL ! int count) // 1 to count once, 10 to init { hash_T hash; hashitem_T *hi; *************** *** 1819,1825 **** else { wc = HI2WC(hi); ! if ((wc->wc_count += count) < (unsigned)count) /* check for overflow */ wc->wc_count = MAXWORDCOUNT; } } --- 1819,1825 ---- else { wc = HI2WC(hi); ! if ((wc->wc_count += count) < (unsigned)count) // check for overflow wc->wc_count = MAXWORDCOUNT; } } *************** *** 1842,1848 **** #define SY_MAXLEN 30 typedef struct syl_item_S { ! char_u sy_chars[SY_MAXLEN]; /* the sequence of chars */ int sy_len; } syl_item_T; --- 1842,1848 ---- #define SY_MAXLEN 30 typedef struct syl_item_S { ! char_u sy_chars[SY_MAXLEN]; // the sequence of chars int sy_len; } syl_item_T; *************** *** 1863,1869 **** while (p != NULL) { *p++ = NUL; ! if (*p == NUL) /* trailing slash */ break; s = p; p = vim_strchr(p, '/'); --- 1863,1869 ---- while (p != NULL) { *p++ = NUL; ! if (*p == NUL) // trailing slash break; s = p; p = vim_strchr(p, '/'); *************** *** 1904,1910 **** for (p = word; *p != NUL; p += len) { ! /* When running into a space reset counter. */ if (*p == ' ') { len = 1; --- 1904,1910 ---- for (p = word; *p != NUL; p += len) { ! // When running into a space reset counter. if (*p == ' ') { len = 1; *************** *** 1912,1918 **** continue; } ! /* Find longest match of syllable items. */ len = 0; for (i = 0; i < slang->sl_syl_items.ga_len; ++i) { --- 1912,1918 ---- continue; } ! // Find longest match of syllable items. len = 0; for (i = 0; i < slang->sl_syl_items.ga_len; ++i) { *************** *** 1921,1942 **** && STRNCMP(p, syl->sy_chars, syl->sy_len) == 0) len = syl->sy_len; } ! if (len != 0) /* found a match, count syllable */ { ++cnt; skip = FALSE; } else { ! /* No recognized syllable item, at least a syllable char then? */ c = mb_ptr2char(p); len = (*mb_ptr2len)(p); if (vim_strchr(slang->sl_syllable, c) == NULL) ! skip = FALSE; /* No, search for next syllable */ else if (!skip) { ! ++cnt; /* Yes, count it */ ! skip = TRUE; /* don't count following syllable chars */ } } } --- 1921,1942 ---- && STRNCMP(p, syl->sy_chars, syl->sy_len) == 0) len = syl->sy_len; } ! if (len != 0) // found a match, count syllable { ++cnt; skip = FALSE; } else { ! // No recognized syllable item, at least a syllable char then? c = mb_ptr2char(p); len = (*mb_ptr2len)(p); if (vim_strchr(slang->sl_syllable, c) == NULL) ! skip = FALSE; // No, search for next syllable else if (!skip) { ! ++cnt; // Yes, count it ! skip = TRUE; // don't count following syllable chars } } } *************** *** 1976,1984 **** set_bufref(&bufref, wp->w_buffer); ! /* We don't want to do this recursively. May happen when a language is ! * not available and the SpellFileMissing autocommand opens a new buffer ! * in which 'spell' is set. */ if (recursive) return NULL; recursive = TRUE; --- 1976,1984 ---- set_bufref(&bufref, wp->w_buffer); ! // We don't want to do this recursively. May happen when a language is ! // not available and the SpellFileMissing autocommand opens a new buffer ! // in which 'spell' is set. if (recursive) return NULL; recursive = TRUE; *************** *** 1986,2000 **** ga_init2(&ga, sizeof(langp_T), 2); clear_midword(wp); ! /* Make a copy of 'spelllang', the SpellFileMissing autocommands may change ! * it under our fingers. */ spl_copy = vim_strsave(wp->w_s->b_p_spl); if (spl_copy == NULL) goto theend; wp->w_s->b_cjk = 0; ! /* Loop over comma separated language names. */ for (splp = spl_copy; *splp != NUL; ) { // Get one language name. --- 1986,2000 ---- ga_init2(&ga, sizeof(langp_T), 2); clear_midword(wp); ! // Make a copy of 'spelllang', the SpellFileMissing autocommands may change ! // it under our fingers. spl_copy = vim_strsave(wp->w_s->b_p_spl); if (spl_copy == NULL) goto theend; wp->w_s->b_cjk = 0; ! // Loop over comma separated language names. for (splp = spl_copy; *splp != NUL; ) { // Get one language name. *************** *** 2011,2024 **** continue; } ! /* If the name ends in ".spl" use it as the name of the spell file. ! * If there is a region name let "region" point to it and remove it ! * from the name. */ if (len > 4 && fnamecmp(lang + len - 4, ".spl") == 0) { filename = TRUE; ! /* Locate a region and remove it from the file name. */ p = vim_strchr(gettail(lang), '_'); if (p != NULL && ASCII_ISALPHA(p[1]) && ASCII_ISALPHA(p[2]) && !ASCII_ISALPHA(p[3])) --- 2011,2024 ---- continue; } ! // If the name ends in ".spl" use it as the name of the spell file. ! // If there is a region name let "region" point to it and remove it ! // from the name. if (len > 4 && fnamecmp(lang + len - 4, ".spl") == 0) { filename = TRUE; ! // Locate a region and remove it from the file name. p = vim_strchr(gettail(lang), '_'); if (p != NULL && ASCII_ISALPHA(p[1]) && ASCII_ISALPHA(p[2]) && !ASCII_ISALPHA(p[3])) *************** *** 2030,2036 **** else dont_use_region = TRUE; ! /* Check if we loaded this language before. */ for (slang = first_lang; slang != NULL; slang = slang->sl_next) if (fullpathcmp(lang, slang->sl_fname, FALSE, TRUE) == FPC_SAME) break; --- 2030,2036 ---- else dont_use_region = TRUE; ! // Check if we loaded this language before. for (slang = first_lang; slang != NULL; slang = slang->sl_next) if (fullpathcmp(lang, slang->sl_fname, FALSE, TRUE) == FPC_SAME) break; *************** *** 2047,2053 **** else dont_use_region = TRUE; ! /* Check if we loaded this language before. */ for (slang = first_lang; slang != NULL; slang = slang->sl_next) if (STRICMP(lang, slang->sl_name) == 0) break; --- 2047,2053 ---- else dont_use_region = TRUE; ! // Check if we loaded this language before. for (slang = first_lang; slang != NULL; slang = slang->sl_next) if (STRICMP(lang, slang->sl_name) == 0) break; *************** *** 2055,2068 **** if (region != NULL) { ! /* If the region differs from what was used before then don't ! * use it for 'spellfile'. */ if (use_region != NULL && STRCMP(region, use_region) != 0) dont_use_region = TRUE; use_region = region; } ! /* If not found try loading the language now. */ if (slang == NULL) { if (filename) --- 2055,2068 ---- if (region != NULL) { ! // If the region differs from what was used before then don't ! // use it for 'spellfile'. if (use_region != NULL && STRCMP(region, use_region) != 0) dont_use_region = TRUE; use_region = region; } ! // If not found try loading the language now. if (slang == NULL) { if (filename) *************** *** 2070,2077 **** else { spell_load_lang(lang); ! /* SpellFileMissing autocommands may do anything, including ! * destroying the buffer we are using... */ if (!bufref_valid(&bufref)) { ret_msg = N_("E797: SpellFileMissing autocommand deleted buffer"); --- 2070,2077 ---- else { spell_load_lang(lang); ! // SpellFileMissing autocommands may do anything, including ! // destroying the buffer we are using... if (!bufref_valid(&bufref)) { ret_msg = N_("E797: SpellFileMissing autocommand deleted buffer"); *************** *** 2091,2109 **** region_mask = REGION_ALL; if (!filename && region != NULL) { ! /* find region in sl_regions */ c = find_region(slang->sl_regions, region); if (c == REGION_ALL) { if (slang->sl_add) { if (*slang->sl_regions != NUL) ! /* This addition file is for other regions. */ region_mask = 0; } else ! /* This is probably an error. Give a warning and ! * accept the words anyway. */ smsg(_("Warning: region %s not supported"), region); } --- 2091,2109 ---- region_mask = REGION_ALL; if (!filename && region != NULL) { ! // find region in sl_regions c = find_region(slang->sl_regions, region); if (c == REGION_ALL) { if (slang->sl_add) { if (*slang->sl_regions != NUL) ! // This addition file is for other regions. region_mask = 0; } else ! // This is probably an error. Give a warning and ! // accept the words anyway. smsg(_("Warning: region %s not supported"), region); } *************** *** 2129,2155 **** } } ! /* round 0: load int_wordlist, if possible. ! * round 1: load first name in 'spellfile'. ! * round 2: load second name in 'spellfile. ! * etc. */ spf = curwin->w_s->b_p_spf; for (round = 0; round == 0 || *spf != NUL; ++round) { if (round == 0) { ! /* Internal wordlist, if there is one. */ if (int_wordlist == NULL) continue; int_wordlist_spl(spf_name); } else { ! /* One entry in 'spellfile'. */ copy_option_part(&spf, spf_name, MAXPATHL - 5, ","); STRCAT(spf_name, ".spl"); ! /* If it was already found above then skip it. */ for (c = 0; c < ga.ga_len; ++c) { p = LANGP_ENTRY(ga, c)->lp_slang->sl_fname; --- 2129,2155 ---- } } ! // round 0: load int_wordlist, if possible. ! // round 1: load first name in 'spellfile'. ! // round 2: load second name in 'spellfile. ! // etc. spf = curwin->w_s->b_p_spf; for (round = 0; round == 0 || *spf != NUL; ++round) { if (round == 0) { ! // Internal wordlist, if there is one. if (int_wordlist == NULL) continue; int_wordlist_spl(spf_name); } else { ! // One entry in 'spellfile'. copy_option_part(&spf, spf_name, MAXPATHL - 5, ","); STRCAT(spf_name, ".spl"); ! // If it was already found above then skip it. for (c = 0; c < ga.ga_len; ++c) { p = LANGP_ENTRY(ga, c)->lp_slang->sl_fname; *************** *** 2161,2176 **** continue; } ! /* Check if it was loaded already. */ for (slang = first_lang; slang != NULL; slang = slang->sl_next) if (fullpathcmp(spf_name, slang->sl_fname, FALSE, TRUE) == FPC_SAME) break; if (slang == NULL) { ! /* Not loaded, try loading it now. The language name includes the ! * region name, the region is ignored otherwise. for int_wordlist ! * use an arbitrary name. */ if (round == 0) STRCPY(lang, "internal wordlist"); else --- 2161,2176 ---- continue; } ! // Check if it was loaded already. for (slang = first_lang; slang != NULL; slang = slang->sl_next) if (fullpathcmp(spf_name, slang->sl_fname, FALSE, TRUE) == FPC_SAME) break; if (slang == NULL) { ! // Not loaded, try loading it now. The language name includes the ! // region name, the region is ignored otherwise. for int_wordlist ! // use an arbitrary name. if (round == 0) STRCPY(lang, "internal wordlist"); else *************** *** 2178,2189 **** vim_strncpy(lang, gettail(spf_name), MAXWLEN); p = vim_strchr(lang, '.'); if (p != NULL) ! *p = NUL; /* truncate at ".encoding.add" */ } slang = spell_load_file(spf_name, lang, NULL, TRUE); ! /* If one of the languages has NOBREAK we assume the addition ! * files also have this. */ if (slang != NULL && nobreak) slang->sl_nobreak = TRUE; } --- 2178,2189 ---- vim_strncpy(lang, gettail(spf_name), MAXWLEN); p = vim_strchr(lang, '.'); if (p != NULL) ! *p = NUL; // truncate at ".encoding.add" } slang = spell_load_file(spf_name, lang, NULL, TRUE); ! // If one of the languages has NOBREAK we assume the addition ! // files also have this. if (slang != NULL && nobreak) slang->sl_nobreak = TRUE; } *************** *** 2192,2203 **** region_mask = REGION_ALL; if (use_region != NULL && !dont_use_region) { ! /* find region in sl_regions */ c = find_region(slang->sl_regions, use_region); if (c != REGION_ALL) region_mask = 1 << c; else if (*slang->sl_regions != NUL) ! /* This spell file is for other regions. */ region_mask = 0; } --- 2192,2203 ---- region_mask = REGION_ALL; if (use_region != NULL && !dont_use_region) { ! // find region in sl_regions c = find_region(slang->sl_regions, use_region); if (c != REGION_ALL) region_mask = 1 << c; else if (*slang->sl_regions != NUL) ! // This spell file is for other regions. region_mask = 0; } *************** *** 2213,2235 **** } } ! /* Everything is fine, store the new b_langp value. */ ga_clear(&wp->w_s->b_langp); wp->w_s->b_langp = ga; ! /* For each language figure out what language to use for sound folding and ! * REP items. If the language doesn't support it itself use another one ! * with the same name. E.g. for "en-math" use "en". */ for (i = 0; i < ga.ga_len; ++i) { lp = LANGP_ENTRY(ga, i); ! /* sound folding */ if (lp->lp_slang->sl_sal.ga_len > 0) ! /* language does sound folding itself */ lp->lp_sallang = lp->lp_slang; else ! /* find first similar language that does sound folding */ for (j = 0; j < ga.ga_len; ++j) { lp2 = LANGP_ENTRY(ga, j); --- 2213,2235 ---- } } ! // Everything is fine, store the new b_langp value. ga_clear(&wp->w_s->b_langp); wp->w_s->b_langp = ga; ! // For each language figure out what language to use for sound folding and ! // REP items. If the language doesn't support it itself use another one ! // with the same name. E.g. for "en-math" use "en". for (i = 0; i < ga.ga_len; ++i) { lp = LANGP_ENTRY(ga, i); ! // sound folding if (lp->lp_slang->sl_sal.ga_len > 0) ! // language does sound folding itself lp->lp_sallang = lp->lp_slang; else ! // find first similar language that does sound folding for (j = 0; j < ga.ga_len; ++j) { lp2 = LANGP_ENTRY(ga, j); *************** *** 2242,2253 **** } } ! /* REP items */ if (lp->lp_slang->sl_rep.ga_len > 0) ! /* language has REP items itself */ lp->lp_replang = lp->lp_slang; else ! /* find first similar language that has REP items */ for (j = 0; j < ga.ga_len; ++j) { lp2 = LANGP_ENTRY(ga, j); --- 2242,2253 ---- } } ! // REP items if (lp->lp_slang->sl_rep.ga_len > 0) ! // language has REP items itself lp->lp_replang = lp->lp_slang; else ! // find first similar language that has REP items for (j = 0; j < ga.ga_len; ++j) { lp2 = LANGP_ENTRY(ga, j); *************** *** 2287,2293 **** { char_u *p; ! if (lp->sl_midword == NULL) /* there aren't any */ return; for (p = lp->sl_midword; *p != NUL; ) --- 2287,2293 ---- { char_u *p; ! if (lp->sl_midword == NULL) // there aren't any return; for (p = lp->sl_midword; *p != NUL; ) *************** *** 2301,2311 **** if (c < 256 && l <= 2) wp->w_s->b_spell_ismw[c] = TRUE; else if (wp->w_s->b_spell_ismw_mb == NULL) ! /* First multi-byte char in "b_spell_ismw_mb". */ wp->w_s->b_spell_ismw_mb = vim_strnsave(p, l); else { ! /* Append multi-byte chars to "b_spell_ismw_mb". */ n = (int)STRLEN(wp->w_s->b_spell_ismw_mb); bp = vim_strnsave(wp->w_s->b_spell_ismw_mb, n + l); if (bp != NULL) --- 2301,2311 ---- if (c < 256 && l <= 2) wp->w_s->b_spell_ismw[c] = TRUE; else if (wp->w_s->b_spell_ismw_mb == NULL) ! // First multi-byte char in "b_spell_ismw_mb". wp->w_s->b_spell_ismw_mb = vim_strnsave(p, l); else { ! // Append multi-byte chars to "b_spell_ismw_mb". n = (int)STRLEN(wp->w_s->b_spell_ismw_mb); bp = vim_strnsave(wp->w_s->b_spell_ismw_mb, n + l); if (bp != NULL) *************** *** 2351,2368 **** int captype( char_u *word, ! char_u *end) /* When NULL use up to NUL byte. */ { char_u *p; int c; int firstcap; int allcap; ! int past_second = FALSE; /* past second word char */ ! /* find first letter */ for (p = word; !spell_iswordp_nmw(p, curwin); MB_PTR_ADV(p)) if (end == NULL ? *p == NUL : p >= end) ! return 0; /* only non-word characters, illegal word */ if (has_mbyte) c = mb_ptr2char_adv(&p); else --- 2351,2368 ---- int captype( char_u *word, ! char_u *end) // When NULL use up to NUL byte. { char_u *p; int c; int firstcap; int allcap; ! int past_second = FALSE; // past second word char ! // find first letter for (p = word; !spell_iswordp_nmw(p, curwin); MB_PTR_ADV(p)) if (end == NULL ? *p == NUL : p >= end) ! return 0; // only non-word characters, illegal word if (has_mbyte) c = mb_ptr2char_adv(&p); else *************** *** 2379,2391 **** c = PTR2CHAR(p); if (!SPELL_ISUPPER(c)) { ! /* UUl -> KEEPCAP */ if (past_second && allcap) return WF_KEEPCAP; allcap = FALSE; } else if (!allcap) ! /* UlU -> KEEPCAP */ return WF_KEEPCAP; past_second = TRUE; } --- 2379,2391 ---- c = PTR2CHAR(p); if (!SPELL_ISUPPER(c)) { ! // UUl -> KEEPCAP if (past_second && allcap) return WF_KEEPCAP; allcap = FALSE; } else if (!allcap) ! // UlU -> KEEPCAP return WF_KEEPCAP; past_second = TRUE; } *************** *** 2423,2429 **** slang_T *slang; buf_T *buf; ! /* Go through all buffers and handle 'spelllang'. */ FOR_ALL_BUFFERS(buf) ga_clear(&buf->b_s.b_langp); --- 2423,2429 ---- slang_T *slang; buf_T *buf; ! // Go through all buffers and handle 'spelllang'. FOR_ALL_BUFFERS(buf) ga_clear(&buf->b_s.b_langp); *************** *** 2449,2465 **** { win_T *wp; ! /* Initialize the table for spell_iswordp(). */ init_spell_chartab(); ! /* Unload all allocated memory. */ spell_free_all(); ! /* Go through all buffers and handle 'spelllang'. */ FOR_ALL_WINDOWS(wp) { ! /* Only load the wordlists when 'spelllang' is set and there is a ! * window for this buffer in which 'spell' is set. */ if (*wp->w_s->b_p_spl != NUL) { if (wp->w_p_spell) --- 2449,2465 ---- { win_T *wp; ! // Initialize the table for spell_iswordp(). init_spell_chartab(); ! // Unload all allocated memory. spell_free_all(); ! // Go through all buffers and handle 'spelllang'. FOR_ALL_WINDOWS(wp) { ! // Only load the wordlists when 'spelllang' is set and there is a ! // window for this buffer in which 'spell' is set. if (*wp->w_s->b_p_spl != NUL) { if (wp->w_p_spell) *************** *** 2488,2499 **** if (buf != NULL) { buf->b_spell = TRUE; ! buf->b_p_swf = TRUE; /* may create a swap file */ #ifdef FEAT_CRYPT buf->b_p_key = empty_option; #endif ml_open(buf); ! ml_open_file(buf); /* create swap file now */ } return buf; } --- 2488,2499 ---- if (buf != NULL) { buf->b_spell = TRUE; ! buf->b_p_swf = TRUE; // may create a swap file #ifdef FEAT_CRYPT buf->b_p_key = empty_option; #endif ml_open(buf); ! ml_open_file(buf); // create swap file now } return buf; } *************** *** 2520,2526 **** { 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) --- 2520,2526 ---- { 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) *************** *** 2529,2536 **** sp->st_upper[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) --- 2529,2536 ---- sp->st_upper[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) *************** *** 2562,2568 **** clear_spell_chartab(&spelltab); if (enc_dbcs) { ! /* DBCS: assume double-wide characters are word characters. */ for (i = 128; i <= 255; ++i) if (MB_BYTE2LEN(i) == 2) spelltab.st_isw[i] = TRUE; --- 2562,2568 ---- clear_spell_chartab(&spelltab); if (enc_dbcs) { ! // DBCS: assume double-wide characters are word characters. for (i = 128; i <= 255; ++i) if (MB_BYTE2LEN(i) == 2) spelltab.st_isw[i] = TRUE; *************** *** 2576,2591 **** spelltab.st_isu[i] = utf_isupper(i); spelltab.st_isw[i] = spelltab.st_isu[i] || utf_islower(i); ! /* The folded/upper-cased value is different between latin1 and ! * utf8 for 0xb5, causing E763 for no good reason. Use the latin1 ! * value for utf-8 to avoid this. */ spelltab.st_fold[i] = (f < 256) ? f : i; spelltab.st_upper[i] = (u < 256) ? u : i; } } else { ! /* Rough guess: use locale-dependent library functions. */ for (i = 128; i < 256; ++i) { if (MB_ISUPPER(i)) --- 2576,2591 ---- spelltab.st_isu[i] = utf_isupper(i); spelltab.st_isw[i] = spelltab.st_isu[i] || utf_islower(i); ! // The folded/upper-cased value is different between latin1 and ! // utf8 for 0xb5, causing E763 for no good reason. Use the latin1 ! // value for utf-8 to avoid this. spelltab.st_fold[i] = (f < 256) ? f : i; spelltab.st_upper[i] = (u < 256) ? u : i; } } else { ! // Rough guess: use locale-dependent library functions. for (i = 128; i < 256; ++i) { if (MB_ISUPPER(i)) *************** *** 2613,2619 **** int spell_iswordp( char_u *p, ! win_T *wp) /* buffer used */ { char_u *s; int l; --- 2613,2619 ---- int spell_iswordp( char_u *p, ! win_T *wp) // buffer used { char_u *s; int l; *************** *** 2625,2633 **** s = p; if (l == 1) { ! /* be quick for ASCII */ if (wp->w_s->b_spell_ismw[*p]) ! s = p + 1; /* skip a mid-word character */ } else { --- 2625,2633 ---- s = p; if (l == 1) { ! // be quick for ASCII if (wp->w_s->b_spell_ismw[*p]) ! s = p + 1; // skip a mid-word character } else { *************** *** 2676,2682 **** spell_mb_isword_class(int cl, win_T *wp) { if (wp->w_s->b_cjk) ! /* East Asian characters are not considered word characters. */ return cl == 2 || cl == 0x2800; return cl >= 2 && cl != 0x2070 && cl != 0x2080 && cl != 3; } --- 2676,2682 ---- spell_mb_isword_class(int cl, win_T *wp) { if (wp->w_s->b_cjk) ! // East Asian characters are not considered word characters. return cl == 2 || cl == 0x2800; return cl >= 2 && cl != 0x2070 && cl != 0x2080 && cl != 3; } *************** *** 2727,2733 **** if (len >= buflen) { buf[0] = NUL; ! return FAIL; /* result will not fit */ } if (has_mbyte) --- 2727,2733 ---- if (len >= buflen) { buf[0] = NUL; ! return FAIL; // result will not fit } if (has_mbyte) *************** *** 2736,2742 **** char_u *p; int c; ! /* Fold one character at a time. */ for (p = str; p < str + len; ) { if (outi + MB_MAXBYTES > buflen) --- 2736,2742 ---- char_u *p; int c; ! // Fold one character at a time. for (p = str; p < str + len; ) { if (outi + MB_MAXBYTES > buflen) *************** *** 2751,2757 **** } else { ! /* Be quick for non-multibyte encodings. */ for (i = 0; i < len; ++i) buf[i] = spelltab.st_fold[str[i]]; buf[i] = NUL; --- 2751,2757 ---- } else { ! // Be quick for non-multibyte encodings. for (i = 0; i < len; ++i) buf[i] = spelltab.st_fold[str[i]]; buf[i] = NUL; *************** *** 2781,2788 **** endcol = 0; if (getwhitecols(line) >= (int)col) { ! /* At start of line, check if previous line is empty or sentence ! * ends there. */ if (lnum == 1) need_cap = TRUE; else --- 2781,2788 ---- endcol = 0; if (getwhitecols(line) >= (int)col) { ! // At start of line, check if previous line is empty or sentence ! // ends there. if (lnum == 1) need_cap = TRUE; else *************** *** 2792,2798 **** need_cap = TRUE; else { ! /* Append a space in place of the line break. */ line_copy = concat_str(line, (char_u *)" "); line = line_copy; endcol = (colnr_T)STRLEN(line); --- 2792,2798 ---- need_cap = TRUE; else { ! // Append a space in place of the line break. line_copy = concat_str(line, (char_u *)" "); line = line_copy; endcol = (colnr_T)STRLEN(line); *************** *** 2804,2810 **** if (endcol > 0) { ! /* Check if sentence ends before the bad word. */ regmatch.regprog = curwin->w_s->b_cap_prog; regmatch.rm_ic = FALSE; p = line + endcol; --- 2804,2810 ---- if (endcol > 0) { ! // Check if sentence ends before the bad word. regmatch.regprog = curwin->w_s->b_cap_prog; regmatch.rm_ic = FALSE; p = line + endcol; *************** *** 2865,2872 **** || u_save_cursor() == FAIL) break; ! /* Only replace when the right word isn't there yet. This happens ! * when changing "etc" to "etc.". */ line = ml_get_curline(); if (addlen <= 0 || STRNCMP(line + curwin->w_cursor.col, repl_to, STRLEN(repl_to)) != 0) --- 2865,2872 ---- || u_save_cursor() == FAIL) break; ! // Only replace when the right word isn't there yet. This happens ! // when changing "etc" to "etc.". line = ml_get_curline(); if (addlen <= 0 || STRNCMP(line + curwin->w_cursor.col, repl_to, STRLEN(repl_to)) != 0) *************** *** 2909,2915 **** onecap_copy( char_u *word, char_u *wcopy, ! int upper) /* TRUE: first letter made upper case */ { char_u *p; int c; --- 2909,2915 ---- onecap_copy( char_u *word, char_u *wcopy, ! int upper) // TRUE: first letter made upper case { char_u *p; int c; *************** *** 2953,2960 **** else c = *s++; ! /* We only change 0xdf to SS when we are certain latin1 is used. It ! * would cause weird errors in other 8-bit encodings. */ if (enc_latin1like && c == 0xdf) { c = 'S'; --- 2953,2960 ---- else c = *s++; ! // We only change 0xdf to SS when we are certain latin1 is used. It ! // would cause weird errors in other 8-bit encodings. if (enc_latin1like && c == 0xdf) { c = 'S'; *************** *** 3005,3017 **** make_case_word(char_u *fword, char_u *cword, int flags) { if (flags & WF_ALLCAP) ! /* Make it all upper-case */ allcap_copy(fword, cword); else if (flags & WF_ONECAP) ! /* Make the first letter upper-case */ onecap_copy(fword, cword, TRUE); else ! /* Use goodword as-is. */ STRCPY(cword, fword); } --- 3005,3017 ---- make_case_word(char_u *fword, char_u *cword, int flags) { if (flags & WF_ALLCAP) ! // Make it all upper-case allcap_copy(fword, cword); else if (flags & WF_ONECAP) ! // Make the first letter upper-case onecap_copy(fword, cword, TRUE); else ! // Use goodword as-is. STRCPY(cword, fword); } *************** *** 3028,3046 **** int lpi; if (curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL) ! /* Use the sound-folding of the first language that supports it. */ for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) { lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); if (lp->lp_slang->sl_sal.ga_len > 0) { ! /* soundfold the word */ spell_soundfold(lp->lp_slang, word, FALSE, sound); return vim_strsave(sound); } } ! /* No language with sound folding, return word as-is. */ return vim_strsave(word); } #endif --- 3028,3046 ---- int lpi; if (curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL) ! // Use the sound-folding of the first language that supports it. for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) { lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); if (lp->lp_slang->sl_sal.ga_len > 0) { ! // soundfold the word spell_soundfold(lp->lp_slang, word, FALSE, sound); return vim_strsave(sound); } } ! // No language with sound folding, return word as-is. return vim_strsave(word); } #endif *************** *** 3061,3078 **** spell_soundfold( slang_T *slang, char_u *inword, ! int folded, /* "inword" is already case-folded */ char_u *res) { char_u fword[MAXWLEN]; char_u *word; if (slang->sl_sofo) ! /* SOFOFROM and SOFOTO used */ spell_soundfold_sofo(slang, inword, res); else { ! /* SAL items used. Requires the word to be case-folded. */ if (folded) word = inword; else --- 3061,3078 ---- spell_soundfold( slang_T *slang, char_u *inword, ! int folded, // "inword" is already case-folded char_u *res) { char_u fword[MAXWLEN]; char_u *word; if (slang->sl_sofo) ! // SOFOFROM and SOFOTO used spell_soundfold_sofo(slang, inword, res); else { ! // SAL items used. Requires the word to be case-folded. if (folded) word = inword; else *************** *** 3104,3111 **** int prevc = 0; int *ip; ! /* The sl_sal_first[] table contains the translation for chars up to ! * 255, sl_sal the rest. */ for (s = inword; *s != NUL; ) { c = mb_cptr2char_adv(&s); --- 3104,3111 ---- int prevc = 0; int *ip; ! // The sl_sal_first[] table contains the translation for chars up to ! // 255, sl_sal the rest. for (s = inword; *s != NUL; ) { c = mb_cptr2char_adv(&s); *************** *** 3116,3132 **** else { ip = ((int **)slang->sl_sal.ga_data)[c & 0xff]; ! if (ip == NULL) /* empty list, can't match */ c = NUL; else ! for (;;) /* find "c" in the list */ { ! if (*ip == 0) /* not found */ { c = NUL; break; } ! if (*ip == c) /* match! */ { c = ip[1]; break; --- 3116,3132 ---- else { ip = ((int **)slang->sl_sal.ga_data)[c & 0xff]; ! if (ip == NULL) // empty list, can't match c = NUL; else ! for (;;) // find "c" in the list { ! if (*ip == 0) // not found { c = NUL; break; } ! if (*ip == c) // match! { c = ip[1]; break; *************** *** 3146,3152 **** } else { ! /* The sl_sal_first[] table contains the translation. */ for (s = inword; (c = *s) != NUL; ++s) { if (VIM_ISWHITE(c)) --- 3146,3152 ---- } else { ! // The sl_sal_first[] table contains the translation. for (s = inword; (c = *s) != NUL; ++s) { if (VIM_ISWHITE(c)) *************** *** 3180,3187 **** int p0 = -333; int c0; ! /* Remove accents, if wanted. We actually remove all non-word characters. ! * But keep white space. We need a copy, the word may be changed here. */ if (slang->sl_rem_accents) { t = word; --- 3180,3187 ---- int p0 = -333; int c0; ! // Remove accents, if wanted. We actually remove all non-word characters. ! // But keep white space. We need a copy, the word may be changed here. if (slang->sl_rem_accents) { t = word; *************** *** 3213,3229 **** i = reslen = z = 0; while ((c = word[i]) != NUL) { ! /* Start with the first rule that has the character in the word. */ n = slang->sl_sal_first[c]; z0 = 0; if (n >= 0) { ! /* check all rules for the same letter */ for (; (s = smp[n].sm_lead)[0] == c; ++n) { ! /* Quickly skip entries that don't match the word. Most ! * entries are less then three chars, optimize for that. */ k = smp[n].sm_leadlen; if (k > 1) { --- 3213,3229 ---- i = reslen = z = 0; while ((c = word[i]) != NUL) { ! // Start with the first rule that has the character in the word. n = slang->sl_sal_first[c]; z0 = 0; if (n >= 0) { ! // check all rules for the same letter for (; (s = smp[n].sm_lead)[0] == c; ++n) { ! // Quickly skip entries that don't match the word. Most ! // entries are less then three chars, optimize for that. k = smp[n].sm_leadlen; if (k > 1) { *************** *** 3241,3247 **** if ((pf = smp[n].sm_oneof) != NULL) { ! /* Check for match with one of the chars in "sm_oneof". */ while (*pf != NUL && *pf != word[i + k]) ++pf; if (*pf == NUL) --- 3241,3247 ---- if ((pf = smp[n].sm_oneof) != NULL) { ! // Check for match with one of the chars in "sm_oneof". while (*pf != NUL && *pf != word[i + k]) ++pf; if (*pf == NUL) *************** *** 3249,3255 **** ++k; } s = smp[n].sm_rules; ! pri = 5; /* default priority */ p0 = *s; k0 = k; --- 3249,3255 ---- ++k; } s = smp[n].sm_rules; ! pri = 5; // default priority p0 = *s; k0 = k; *************** *** 3262,3268 **** s++; if (VIM_ISDIGIT(*s)) { ! /* determine priority */ pri = *s - '0'; s++; } --- 3262,3268 ---- s++; if (VIM_ISDIGIT(*s)) { ! // determine priority pri = *s - '0'; s++; } *************** *** 3279,3297 **** && spell_iswordp(word + i - 1, curwin) && (!spell_iswordp(word + i + k0, curwin)))) { ! /* search for followup rules, if: */ ! /* followup and k > 1 and NO '-' in searchstring */ c0 = word[i + k - 1]; n0 = slang->sl_sal_first[c0]; if (slang->sl_followup && k > 1 && n0 >= 0 && p0 != '-' && word[i + k] != NUL) { ! /* test follow-up rule for "word[i + k]" */ for ( ; (s = smp[n0].sm_lead)[0] == c0; ++n0) { ! /* Quickly skip entries that don't match the word. ! * */ k0 = smp[n0].sm_leadlen; if (k0 > 1) { --- 3279,3297 ---- && spell_iswordp(word + i - 1, curwin) && (!spell_iswordp(word + i + k0, curwin)))) { ! // search for followup rules, if: ! // followup and k > 1 and NO '-' in searchstring c0 = word[i + k - 1]; n0 = slang->sl_sal_first[c0]; if (slang->sl_followup && k > 1 && n0 >= 0 && p0 != '-' && word[i + k] != NUL) { ! // test follow-up rule for "word[i + k]" for ( ; (s = smp[n0].sm_lead)[0] == c0; ++n0) { ! // Quickly skip entries that don't match the word. ! // k0 = smp[n0].sm_leadlen; if (k0 > 1) { *************** *** 3311,3318 **** if ((pf = smp[n0].sm_oneof) != NULL) { ! /* Check for match with one of the chars in ! * "sm_oneof". */ while (*pf != NUL && *pf != word[i + k0]) ++pf; if (*pf == NUL) --- 3311,3318 ---- if ((pf = smp[n0].sm_oneof) != NULL) { ! // Check for match with one of the chars in ! // "sm_oneof". while (*pf != NUL && *pf != word[i + k0]) ++pf; if (*pf == NUL) *************** *** 3324,3331 **** s = smp[n0].sm_rules; while (*s == '-') { ! /* "k0" gets NOT reduced because ! * "if (k0 == k)" */ s++; } if (*s == '<') --- 3324,3331 ---- s = smp[n0].sm_rules; while (*s == '-') { ! // "k0" gets NOT reduced because ! // "if (k0 == k)" s++; } if (*s == '<') *************** *** 3337,3355 **** } if (*s == NUL ! /* *s == '^' cuts */ || (*s == '$' && !spell_iswordp(word + i + k0, curwin))) { if (k0 == k) ! /* this is just a piece of the string */ continue; if (p0 < pri) ! /* priority too low */ continue; ! /* rule fits; stop search */ break; } } --- 3337,3355 ---- } if (*s == NUL ! // *s == '^' cuts || (*s == '$' && !spell_iswordp(word + i + k0, curwin))) { if (k0 == k) ! // this is just a piece of the string continue; if (p0 < pri) ! // priority too low continue; ! // rule fits; stop search break; } } *************** *** 3358,3364 **** continue; } ! /* replace string */ s = smp[n].sm_to; if (s == NULL) s = (char_u *)""; --- 3358,3364 ---- continue; } ! // replace string s = smp[n].sm_to; if (s == NULL) s = (char_u *)""; *************** *** 3366,3372 **** p0 = (vim_strchr(pf, '<') != NULL) ? 1 : 0; if (p0 == 1 && z == 0) { ! /* rule with '<' is used */ if (reslen > 0 && *s != NUL && (res[reslen - 1] == c || res[reslen - 1] == *s)) reslen--; --- 3366,3372 ---- p0 = (vim_strchr(pf, '<') != NULL) ? 1 : 0; if (p0 == 1 && z == 0) { ! // rule with '<' is used if (reslen > 0 && *s != NUL && (res[reslen - 1] == c || res[reslen - 1] == *s)) reslen--; *************** *** 3382,3393 **** if (k > k0) STRMOVE(word + i + k0, word + i + k); ! /* new "actual letter" */ c = word[i]; } else { ! /* no '<' rule used */ i += k - 1; z = 0; while (*s != NUL && s[1] != NUL && reslen < MAXWLEN) --- 3382,3393 ---- if (k > k0) STRMOVE(word + i + k0, word + i + k); ! // new "actual letter" c = word[i]; } else { ! // no '<' rule used i += k - 1; z = 0; while (*s != NUL && s[1] != NUL && reslen < MAXWLEN) *************** *** 3396,3402 **** res[reslen++] = *s; s++; } ! /* new "actual letter" */ c = *s; if (strstr((char *)pf, "^^") != NULL) { --- 3396,3402 ---- res[reslen++] = *s; s++; } ! // new "actual letter" c = *s; if (strstr((char *)pf, "^^") != NULL) { *************** *** 3422,3428 **** if (k && !p0 && reslen < MAXWLEN && c != NUL && (!slang->sl_collapse || reslen == 0 || res[reslen - 1] != c)) ! /* condense only double letters */ res[reslen++] = c; i++; --- 3422,3428 ---- if (k && !p0 && reslen < MAXWLEN && c != NUL && (!slang->sl_collapse || reslen == 0 || res[reslen - 1] != c)) ! // condense only double letters res[reslen++] = c; i++; *************** *** 3501,3520 **** i = reslen = z = 0; while ((c = word[i]) != NUL) { ! /* Start with the first rule that has the character in the word. */ n = slang->sl_sal_first[c & 0xff]; z0 = 0; if (n >= 0) { ! /* Check all rules for the same index byte. ! * If c is 0x300 need extra check for the end of the array, as ! * (c & 0xff) is NUL. */ 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. */ if (c != ws[0]) continue; k = smp[n].sm_leadlen; --- 3501,3520 ---- i = reslen = z = 0; while ((c = word[i]) != NUL) { ! // Start with the first rule that has the character in the word. n = slang->sl_sal_first[c & 0xff]; z0 = 0; if (n >= 0) { ! // Check all rules for the same index byte. ! // If c is 0x300 need extra check for the end of the array, as ! // (c & 0xff) is NUL. 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. if (c != ws[0]) continue; k = smp[n].sm_leadlen; *************** *** 3534,3540 **** if ((pf = smp[n].sm_oneof_w) != NULL) { ! /* Check for match with one of the chars in "sm_oneof". */ while (*pf != NUL && *pf != word[i + k]) ++pf; if (*pf == NUL) --- 3534,3540 ---- if ((pf = smp[n].sm_oneof_w) != NULL) { ! // Check for match with one of the chars in "sm_oneof". while (*pf != NUL && *pf != word[i + k]) ++pf; if (*pf == NUL) *************** *** 3542,3548 **** ++k; } s = smp[n].sm_rules; ! pri = 5; /* default priority */ p0 = *s; k0 = k; --- 3542,3548 ---- ++k; } s = smp[n].sm_rules; ! pri = 5; // default priority p0 = *s; k0 = k; *************** *** 3555,3561 **** s++; if (VIM_ISDIGIT(*s)) { ! /* determine priority */ pri = *s - '0'; s++; } --- 3555,3561 ---- s++; if (VIM_ISDIGIT(*s)) { ! // determine priority pri = *s - '0'; s++; } *************** *** 3572,3592 **** && spell_iswordp_w(word + i - 1, curwin) && (!spell_iswordp_w(word + i + k0, curwin)))) { ! /* search for followup rules, if: */ ! /* followup and k > 1 and NO '-' in searchstring */ c0 = word[i + k - 1]; n0 = slang->sl_sal_first[c0 & 0xff]; if (slang->sl_followup && k > 1 && n0 >= 0 && p0 != '-' && word[i + k] != NUL) { ! /* Test follow-up rule for "word[i + k]"; loop over ! * all entries with the same index byte. */ for ( ; ((ws = smp[n0].sm_lead_w)[0] & 0xff) == (c0 & 0xff); ++n0) { ! /* Quickly skip entries that don't match the word. ! */ if (c0 != ws[0]) continue; k0 = smp[n0].sm_leadlen; --- 3572,3591 ---- && spell_iswordp_w(word + i - 1, curwin) && (!spell_iswordp_w(word + i + k0, curwin)))) { ! // search for followup rules, if: ! // followup and k > 1 and NO '-' in searchstring c0 = word[i + k - 1]; n0 = slang->sl_sal_first[c0 & 0xff]; if (slang->sl_followup && k > 1 && n0 >= 0 && p0 != '-' && word[i + k] != NUL) { ! // Test follow-up rule for "word[i + k]"; loop over ! // all entries with the same index byte. for ( ; ((ws = smp[n0].sm_lead_w)[0] & 0xff) == (c0 & 0xff); ++n0) { ! // Quickly skip entries that don't match the word. if (c0 != ws[0]) continue; k0 = smp[n0].sm_leadlen; *************** *** 3608,3615 **** if ((pf = smp[n0].sm_oneof_w) != NULL) { ! /* Check for match with one of the chars in ! * "sm_oneof". */ while (*pf != NUL && *pf != word[i + k0]) ++pf; if (*pf == NUL) --- 3607,3614 ---- if ((pf = smp[n0].sm_oneof_w) != NULL) { ! // Check for match with one of the chars in ! // "sm_oneof". while (*pf != NUL && *pf != word[i + k0]) ++pf; if (*pf == NUL) *************** *** 3621,3628 **** s = smp[n0].sm_rules; while (*s == '-') { ! /* "k0" gets NOT reduced because ! * "if (k0 == k)" */ s++; } if (*s == '<') --- 3620,3627 ---- s = smp[n0].sm_rules; while (*s == '-') { ! // "k0" gets NOT reduced because ! // "if (k0 == k)" s++; } if (*s == '<') *************** *** 3634,3652 **** } if (*s == NUL ! /* *s == '^' cuts */ || (*s == '$' && !spell_iswordp_w(word + i + k0, curwin))) { if (k0 == k) ! /* this is just a piece of the string */ continue; if (p0 < pri) ! /* priority too low */ continue; ! /* rule fits; stop search */ break; } } --- 3633,3651 ---- } if (*s == NUL ! // *s == '^' cuts || (*s == '$' && !spell_iswordp_w(word + i + k0, curwin))) { if (k0 == k) ! // this is just a piece of the string continue; if (p0 < pri) ! // priority too low continue; ! // rule fits; stop search break; } } *************** *** 3656,3668 **** continue; } ! /* replace string */ ws = smp[n].sm_to_w; s = smp[n].sm_rules; p0 = (vim_strchr(s, '<') != NULL) ? 1 : 0; if (p0 == 1 && z == 0) { ! /* rule with '<' is used */ if (reslen > 0 && ws != NULL && *ws != NUL && (wres[reslen - 1] == c || wres[reslen - 1] == *ws)) --- 3655,3667 ---- continue; } ! // replace string ws = smp[n].sm_to_w; s = smp[n].sm_rules; p0 = (vim_strchr(s, '<') != NULL) ? 1 : 0; if (p0 == 1 && z == 0) { ! // rule with '<' is used if (reslen > 0 && ws != NULL && *ws != NUL && (wres[reslen - 1] == c || wres[reslen - 1] == *ws)) *************** *** 3681,3692 **** mch_memmove(word + i + k0, word + i + k, sizeof(int) * (wordlen - (i + k) + 1)); ! /* new "actual letter" */ c = word[i]; } else { ! /* no '<' rule used */ i += k - 1; z = 0; if (ws != NULL) --- 3680,3691 ---- mch_memmove(word + i + k0, word + i + k, sizeof(int) * (wordlen - (i + k) + 1)); ! // new "actual letter" c = word[i]; } else { ! // no '<' rule used i += k - 1; z = 0; if (ws != NULL) *************** *** 3697,3703 **** wres[reslen++] = *ws; ws++; } ! /* new "actual letter" */ if (ws == NULL) c = NUL; else --- 3696,3702 ---- wres[reslen++] = *ws; ws++; } ! // new "actual letter" if (ws == NULL) c = NUL; else *************** *** 3727,3733 **** if (k && !p0 && reslen < MAXWLEN && c != NUL && (!slang->sl_collapse || reslen == 0 || wres[reslen - 1] != c)) ! /* condense only double letters */ wres[reslen++] = c; i++; --- 3726,3732 ---- if (k && !p0 && reslen < MAXWLEN && c != NUL && (!slang->sl_collapse || reslen == 0 || wres[reslen - 1] != c)) ! // condense only double letters wres[reslen++] = c; i++; *************** *** 3736,3742 **** } } ! /* Convert wide characters in "wres" to a multi-byte string in "res". */ l = 0; for (n = 0; n < reslen; ++n) { --- 3735,3741 ---- } } ! // Convert wide characters in "wres" to a multi-byte string in "res". l = 0; for (n = 0; n < reslen; ++n) { *************** *** 3777,3787 **** msg_end(); } ! #define DUMPFLAG_KEEPCASE 1 /* round 2: keep-case tree */ ! #define DUMPFLAG_COUNT 2 /* include word count */ ! #define DUMPFLAG_ICASE 4 /* ignore case when finding matches */ ! #define DUMPFLAG_ONECAP 8 /* pattern starts with capital */ ! #define DUMPFLAG_ALLCAP 16 /* pattern is all capitals */ /* * ":spelldump" --- 3776,3786 ---- msg_end(); } ! #define DUMPFLAG_KEEPCASE 1 // round 2: keep-case tree ! #define DUMPFLAG_COUNT 2 // include word count ! #define DUMPFLAG_ICASE 4 // ignore case when finding matches ! #define DUMPFLAG_ONECAP 8 // pattern starts with capital ! #define DUMPFLAG_ALLCAP 16 // pattern is all capitals /* * ":spelldump" *************** *** 3796,3805 **** return; get_option_value((char_u*)"spl", &dummy, &spl, OPT_LOCAL); ! /* Create a new empty buffer in a new window. */ do_cmdline_cmd((char_u *)"new"); ! /* enable spelling locally in the new window */ set_option_value((char_u*)"spell", TRUE, (char_u*)"", OPT_LOCAL); set_option_value((char_u*)"spl", dummy, spl, OPT_LOCAL); vim_free(spl); --- 3795,3804 ---- return; get_option_value((char_u*)"spl", &dummy, &spl, OPT_LOCAL); ! // Create a new empty buffer in a new window. do_cmdline_cmd((char_u *)"new"); ! // enable spelling locally in the new window set_option_value((char_u*)"spell", TRUE, (char_u*)"", OPT_LOCAL); set_option_value((char_u*)"spl", dummy, spl, OPT_LOCAL); vim_free(spl); *************** *** 3809,3815 **** spell_dump_compl(NULL, 0, NULL, eap->forceit ? DUMPFLAG_COUNT : 0); ! /* Delete the empty line that we started with. */ if (curbuf->b_ml.ml_line_count > 1) ml_delete(curbuf->b_ml.ml_line_count, FALSE); --- 3808,3814 ---- spell_dump_compl(NULL, 0, NULL, eap->forceit ? DUMPFLAG_COUNT : 0); ! // Delete the empty line that we started with. if (curbuf->b_ml.ml_line_count > 1) ml_delete(curbuf->b_ml.ml_line_count, FALSE); *************** *** 3824,3833 **** */ void spell_dump_compl( ! char_u *pat, /* leading part of the word */ ! int ic, /* ignore case */ ! int *dir, /* direction for adding matches */ ! int dumpflags_arg) /* DUMPFLAG_* */ { langp_T *lp; slang_T *slang; --- 3823,3832 ---- */ void spell_dump_compl( ! char_u *pat, // leading part of the word ! int ic, // ignore case ! int *dir, // direction for adding matches ! int dumpflags_arg) // DUMPFLAG_* { langp_T *lp; slang_T *slang; *************** *** 3842,3856 **** int depth; int n; int flags; ! char_u *region_names = NULL; /* region names being used */ ! int do_region = TRUE; /* dump region names and numbers */ char_u *p; int lpi; int dumpflags = dumpflags_arg; int patlen; ! /* When ignoring case or when the pattern starts with capital pass this on ! * to dump_word(). */ if (pat != NULL) { if (ic) --- 3841,3855 ---- int depth; int n; int flags; ! char_u *region_names = NULL; // region names being used ! int do_region = TRUE; // dump region names and numbers char_u *p; int lpi; int dumpflags = dumpflags_arg; int patlen; ! // When ignoring case or when the pattern starts with capital pass this on ! // to dump_word(). if (pat != NULL) { if (ic) *************** *** 3865,3883 **** } } ! /* Find out if we can support regions: All languages must support the same ! * regions or none at all. */ for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) { lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); p = lp->lp_slang->sl_regions; if (p[0] != 0) { ! if (region_names == NULL) /* first language with regions */ region_names = p; else if (STRCMP(region_names, p) != 0) { ! do_region = FALSE; /* region names are different */ break; } } --- 3864,3882 ---- } } ! // Find out if we can support regions: All languages must support the same ! // regions or none at all. for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) { lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); p = lp->lp_slang->sl_regions; if (p[0] != 0) { ! if (region_names == NULL) // first language with regions region_names = p; else if (STRCMP(region_names, p) != 0) { ! do_region = FALSE; // region names are different break; } } *************** *** 3901,3907 **** { lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); slang = lp->lp_slang; ! if (slang->sl_fbyts == NULL) /* reloading failed */ continue; if (pat == NULL) --- 3900,3906 ---- { lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); slang = lp->lp_slang; ! if (slang->sl_fbyts == NULL) // reloading failed continue; if (pat == NULL) *************** *** 3910,3924 **** ml_append(lnum++, IObuff, (colnr_T)0, FALSE); } ! /* When matching with a pattern and there are no prefixes only use ! * parts of the tree that match "pat". */ if (pat != NULL && slang->sl_pbyts == NULL) patlen = (int)STRLEN(pat); else patlen = -1; ! /* round 1: case-folded tree ! * round 2: keep-case tree */ for (round = 1; round <= 2; ++round) { if (round == 1) --- 3909,3923 ---- ml_append(lnum++, IObuff, (colnr_T)0, FALSE); } ! // When matching with a pattern and there are no prefixes only use ! // parts of the tree that match "pat". if (pat != NULL && slang->sl_pbyts == NULL) patlen = (int)STRLEN(pat); else patlen = -1; ! // round 1: case-folded tree ! // round 2: keep-case tree for (round = 1; round <= 2; ++round) { if (round == 1) *************** *** 3934,3940 **** idxs = slang->sl_kidxs; } if (byts == NULL) ! continue; /* array is empty */ depth = 0; arridx[0] = 0; --- 3933,3939 ---- idxs = slang->sl_kidxs; } if (byts == NULL) ! continue; // array is empty depth = 0; arridx[0] = 0; *************** *** 3944,3966 **** { if (curi[depth] > byts[arridx[depth]]) { ! /* Done all bytes at this node, go up one level. */ --depth; line_breakcheck(); ins_compl_check_keys(50, FALSE); } else { ! /* Do one more byte at this node. */ n = arridx[depth] + curi[depth]; ++curi[depth]; c = byts[n]; if (c == 0) { ! /* End of word, deal with the word. ! * Don't use keep-case words in the fold-case tree, ! * they will appear in the keep-case tree. ! * Only use the word when the region matches. */ flags = (int)idxs[n]; if ((round == 2 || (flags & WF_KEEPCAP) == 0) && (flags & WF_NEEDCOMP) == 0 --- 3943,3965 ---- { if (curi[depth] > byts[arridx[depth]]) { ! // Done all bytes at this node, go up one level. --depth; line_breakcheck(); ins_compl_check_keys(50, FALSE); } else { ! // Do one more byte at this node. n = arridx[depth] + curi[depth]; ++curi[depth]; c = byts[n]; if (c == 0) { ! // End of word, deal with the word. ! // Don't use keep-case words in the fold-case tree, ! // they will appear in the keep-case tree. ! // Only use the word when the region matches. flags = (int)idxs[n]; if ((round == 2 || (flags & WF_KEEPCAP) == 0) && (flags & WF_NEEDCOMP) == 0 *************** *** 3973,3980 **** if (!do_region) flags &= ~WF_REGION; ! /* Dump the basic word if there is no prefix or ! * when it's the first one. */ c = (unsigned)flags >> 24; if (c == 0 || curi[depth] == 2) { --- 3972,3979 ---- if (!do_region) flags &= ~WF_REGION; ! // Dump the basic word if there is no prefix or ! // when it's the first one. c = (unsigned)flags >> 24; if (c == 0 || curi[depth] == 2) { *************** *** 3984,3990 **** ++lnum; } ! /* Apply the prefix, if there is one. */ if (c != 0) lnum = dump_prefixes(slang, word, pat, dir, dumpflags, flags, lnum); --- 3983,3989 ---- ++lnum; } ! // Apply the prefix, if there is one. if (c != 0) lnum = dump_prefixes(slang, word, pat, dir, dumpflags, flags, lnum); *************** *** 3992,4008 **** } else { ! /* Normal char, go one level deeper. */ word[depth++] = c; arridx[depth] = idxs[n]; curi[depth] = 1; ! /* Check if this characters 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 ! * length changes for multi-byte characters with ! * ignore case... */ if (depth <= patlen && MB_STRNICMP(word, pat, depth) != 0) --depth; --- 3991,4007 ---- } else { ! // Normal char, go one level deeper. word[depth++] = c; arridx[depth] = idxs[n]; curi[depth] = 1; ! // Check if this characters 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 ! // length changes for multi-byte characters with ! // ignore case... if (depth <= patlen && MB_STRNICMP(word, pat, depth) != 0) --depth; *************** *** 4042,4048 **** if ((dumpflags & DUMPFLAG_KEEPCASE) == 0 && (flags & WF_CAPMASK) != 0) { ! /* Need to fix case according to "flags". */ make_case_word(word, cword, flags); p = cword; } --- 4041,4047 ---- if ((dumpflags & DUMPFLAG_KEEPCASE) == 0 && (flags & WF_CAPMASK) != 0) { ! // Need to fix case according to "flags". make_case_word(word, cword, flags); p = cword; } *************** *** 4058,4064 **** if (pat == NULL) { ! /* Add flags and regions after a slash. */ if ((flags & (WF_BANNED | WF_RARE | WF_REGION)) || keepcap) { STRCPY(badword, p); --- 4057,4063 ---- if (pat == NULL) { ! // Add flags and regions after a slash. if ((flags & (WF_BANNED | WF_RARE | WF_REGION)) || keepcap) { STRCPY(badword, p); *************** *** 4080,4086 **** { hashitem_T *hi; ! /* Include the word count for ":spelldump!". */ hi = hash_find(&slang->sl_wordcount, tw); if (!HASHITEM_EMPTY(hi)) { --- 4079,4085 ---- { hashitem_T *hi; ! // Include the word count for ":spelldump!". hi = hash_find(&slang->sl_wordcount, tw); if (!HASHITEM_EMPTY(hi)) { *************** *** 4097,4103 **** : STRNCMP(p, pat, STRLEN(pat)) == 0) && ins_compl_add_infercase(p, (int)STRLEN(p), p_ic, NULL, *dir, FALSE) == OK) ! /* if dir was BACKWARD then honor it just once */ *dir = FORWARD; } --- 4096,4102 ---- : STRNCMP(p, pat, STRLEN(pat)) == 0) && ins_compl_add_infercase(p, (int)STRLEN(p), p_ic, NULL, *dir, FALSE) == OK) ! // if dir was BACKWARD then honor it just once *dir = FORWARD; } *************** *** 4110,4120 **** static linenr_T dump_prefixes( slang_T *slang, ! char_u *word, /* case-folded word */ char_u *pat, int *dir, int dumpflags, ! int flags, /* flags with prefix ID */ linenr_T startlnum) { idx_T arridx[MAXWLEN]; --- 4109,4119 ---- static linenr_T dump_prefixes( slang_T *slang, ! char_u *word, // case-folded word char_u *pat, int *dir, int dumpflags, ! int flags, // flags with prefix ID linenr_T startlnum) { idx_T arridx[MAXWLEN]; *************** *** 4131,4138 **** int len; int i; ! /* If the word starts with a lower-case letter make the word with an ! * upper-case letter in word_up[]. */ c = PTR2CHAR(word); if (SPELL_TOUPPER(c) != c) { --- 4130,4137 ---- int len; int i; ! // If the word starts with a lower-case letter make the word with an ! // upper-case letter in word_up[]. c = PTR2CHAR(word); if (SPELL_TOUPPER(c) != c) { *************** *** 4142,4148 **** byts = slang->sl_pbyts; idxs = slang->sl_pidxs; ! if (byts != NULL) /* array not is empty */ { /* * Loop over all prefixes, building them byte-by-byte in prefix[]. --- 4141,4147 ---- byts = slang->sl_pbyts; idxs = slang->sl_pidxs; ! if (byts != NULL) // array not is empty { /* * Loop over all prefixes, building them byte-by-byte in prefix[]. *************** *** 4157,4175 **** len = byts[n]; if (curi[depth] > len) { ! /* Done all bytes at this node, go up one level. */ --depth; line_breakcheck(); } else { ! /* Do one more byte at this node. */ n += curi[depth]; ++curi[depth]; c = byts[n]; if (c == 0) { ! /* End of prefix, find out how many IDs there are. */ for (i = 1; i < len; ++i) if (byts[n + i] != 0) break; --- 4156,4174 ---- len = byts[n]; if (curi[depth] > len) { ! // Done all bytes at this node, go up one level. --depth; line_breakcheck(); } else { ! // Do one more byte at this node. n += curi[depth]; ++curi[depth]; c = byts[n]; if (c == 0) { ! // End of prefix, find out how many IDs there are. for (i = 1; i < len; ++i) if (byts[n + i] != 0) break; *************** *** 4186,4194 **** ++lnum; } ! /* Check for prefix that matches the word when the ! * first letter is upper-case, but only if the prefix has ! * a condition. */ if (has_word_up) { c = valid_word_prefix(i, n, flags, word_up, slang, --- 4185,4193 ---- ++lnum; } ! // Check for prefix that matches the word when the ! // first letter is upper-case, but only if the prefix has ! // a condition. if (has_word_up) { c = valid_word_prefix(i, n, flags, word_up, slang, *************** *** 4207,4213 **** } else { ! /* Normal char, go one level deeper. */ prefix[depth++] = c; arridx[depth] = idxs[n]; curi[depth] = 1; --- 4206,4212 ---- } else { ! // Normal char, go one level deeper. prefix[depth++] = c; arridx[depth] = idxs[n]; curi[depth] = 1; *************** *** 4250,4256 **** if (no_spell_checking(curwin)) return startcol; ! /* Find a word character before "startcol". */ line = ml_get_curline(); for (p = line + startcol; p > line; ) { --- 4249,4255 ---- if (no_spell_checking(curwin)) return startcol; ! // Find a word character before "startcol". line = ml_get_curline(); for (p = line + startcol; p > line; ) { *************** *** 4259,4265 **** break; } ! /* Go back to start of the word. */ while (p > line) { col = (int)(p - line); --- 4258,4264 ---- break; } ! // Go back to start of the word. while (p > line) { col = (int)(p - line); *** ../vim-8.1.2394/src/spellfile.c 2019-11-07 20:48:38.729213691 +0100 --- src/spellfile.c 2019-12-05 21:20:39.397460675 +0100 *************** *** 241,297 **** #if defined(FEAT_SPELL) || defined(PROTO) ! #ifndef UNIX /* it's in os_unix.h for Unix */ ! # include /* for time_t */ #endif ! #ifndef UNIX /* it's in os_unix.h for Unix */ ! # include /* for time_t */ #endif ! /* Special byte values for . Some are only used in the tree for ! * postponed prefixes, some only in the other trees. This is a bit messy... */ ! #define BY_NOFLAGS 0 /* end of word without flags or region; for ! * postponed prefix: no */ ! #define BY_INDEX 1 /* child is shared, index follows */ ! #define BY_FLAGS 2 /* end of word, byte follows; for ! * postponed prefix: follows */ ! #define BY_FLAGS2 3 /* end of word, and bytes ! * follow; never used in prefix tree */ ! #define BY_SPECIAL BY_FLAGS2 /* highest special byte value */ #define ZERO_FLAG 65009 // used when flag is zero: "0" ! /* Flags used in .spl file for soundsalike flags. */ #define SAL_F0LLOWUP 1 #define SAL_COLLAPSE 2 #define SAL_REM_ACCENTS 4 ! #define VIMSPELLMAGIC "VIMspell" /* string at start of Vim spell file */ #define VIMSPELLMAGICL 8 #define VIMSPELLVERSION 50 ! /* Section IDs. Only renumber them when VIMSPELLVERSION changes! */ ! #define SN_REGION 0 /* section */ ! #define SN_CHARFLAGS 1 /* charflags section */ ! #define SN_MIDWORD 2 /* section */ ! #define SN_PREFCOND 3 /* section */ ! #define SN_REP 4 /* REP items section */ ! #define SN_SAL 5 /* SAL items section */ ! #define SN_SOFO 6 /* soundfolding section */ ! #define SN_MAP 7 /* MAP items section */ ! #define SN_COMPOUND 8 /* compound words section */ ! #define SN_SYLLABLE 9 /* syllable section */ ! #define SN_NOBREAK 10 /* NOBREAK section */ ! #define SN_SUGFILE 11 /* timestamp for .sug file */ ! #define SN_REPSAL 12 /* REPSAL items section */ ! #define SN_WORDS 13 /* common words */ ! #define SN_NOSPLITSUGS 14 /* don't split word for suggestions */ ! #define SN_INFO 15 /* info section */ ! #define SN_NOCOMPOUNDSUGS 16 /* don't compound for suggestions */ ! #define SN_END 255 /* end of sections */ ! #define SNF_REQUIRED 1 /* : required section */ #define CF_WORD 0x01 #define CF_UPPER 0x02 --- 241,297 ---- #if defined(FEAT_SPELL) || defined(PROTO) ! #ifndef UNIX // it's in os_unix.h for Unix ! # include // for time_t #endif ! #ifndef UNIX // it's in os_unix.h for Unix ! # include // for time_t #endif ! // Special byte values for . Some are only used in the tree for ! // postponed prefixes, some only in the other trees. This is a bit messy... ! #define BY_NOFLAGS 0 // end of word without flags or region; for ! // postponed prefix: no ! #define BY_INDEX 1 // child is shared, index follows ! #define BY_FLAGS 2 // end of word, byte follows; for ! // postponed prefix: follows ! #define BY_FLAGS2 3 // end of word, and bytes ! // follow; never used in prefix tree ! #define BY_SPECIAL BY_FLAGS2 // highest special byte value #define ZERO_FLAG 65009 // used when flag is zero: "0" ! // Flags used in .spl file for soundsalike flags. #define SAL_F0LLOWUP 1 #define SAL_COLLAPSE 2 #define SAL_REM_ACCENTS 4 ! #define VIMSPELLMAGIC "VIMspell" // string at start of Vim spell file #define VIMSPELLMAGICL 8 #define VIMSPELLVERSION 50 ! // Section IDs. Only renumber them when VIMSPELLVERSION changes! ! #define SN_REGION 0 // section ! #define SN_CHARFLAGS 1 // charflags section ! #define SN_MIDWORD 2 // section ! #define SN_PREFCOND 3 // section ! #define SN_REP 4 // REP items section ! #define SN_SAL 5 // SAL items section ! #define SN_SOFO 6 // soundfolding section ! #define SN_MAP 7 // MAP items section ! #define SN_COMPOUND 8 // compound words section ! #define SN_SYLLABLE 9 // syllable section ! #define SN_NOBREAK 10 // NOBREAK section ! #define SN_SUGFILE 11 // timestamp for .sug file ! #define SN_REPSAL 12 // REPSAL items section ! #define SN_WORDS 13 // common words ! #define SN_NOSPLITSUGS 14 // don't split word for suggestions ! #define SN_INFO 15 // info section ! #define SN_NOCOMPOUNDSUGS 16 // don't compound for suggestions ! #define SN_END 255 // end of sections ! #define SNF_REQUIRED 1 // : required section #define CF_WORD 0x01 #define CF_UPPER 0x02 *************** *** 341,347 **** char_u *fname, char_u *lang, slang_T *old_lp, ! int silent) /* no error if file doesn't exist */ { FILE *fd; char_u buf[VIMSPELLMAGICL]; --- 341,347 ---- char_u *fname, char_u *lang, slang_T *old_lp, ! int silent) // no error if file doesn't exist { FILE *fd; char_u buf[VIMSPELLMAGICL]; *************** *** 381,398 **** if (lp == NULL) goto endFAIL; ! /* Remember the file name, used to reload the file when it's updated. */ lp->sl_fname = vim_strsave(fname); if (lp->sl_fname == NULL) goto endFAIL; ! /* Check for .add.spl (_add.spl for VMS). */ lp->sl_add = strstr((char *)gettail(fname), SPL_FNAME_ADD) != NULL; } else lp = old_lp; ! /* Set sourcing_name, so that error messages mention the file name. */ sourcing_name = fname; sourcing_lnum = 0; --- 381,398 ---- if (lp == NULL) goto endFAIL; ! // Remember the file name, used to reload the file when it's updated. lp->sl_fname = vim_strsave(fname); if (lp->sl_fname == NULL) goto endFAIL; ! // Check for .add.spl (_add.spl for VMS). lp->sl_add = strstr((char *)gettail(fname), SPL_FNAME_ADD) != NULL; } else lp = old_lp; ! // Set sourcing_name, so that error messages mention the file name. sourcing_name = fname; sourcing_lnum = 0; *************** *** 400,412 **** *
: */ for (i = 0; i < VIMSPELLMAGICL; ++i) ! buf[i] = getc(fd); /* */ if (STRNCMP(buf, VIMSPELLMAGIC, VIMSPELLMAGICL) != 0) { emsg(_("E757: This does not look like a spell file")); goto endFAIL; } ! c = getc(fd); /* */ if (c < VIMSPELLVERSION) { emsg(_("E771: Old spell file, needs to be updated")); --- 400,412 ---- *
: */ for (i = 0; i < VIMSPELLMAGICL; ++i) ! buf[i] = getc(fd); // if (STRNCMP(buf, VIMSPELLMAGIC, VIMSPELLMAGICL) != 0) { emsg(_("E757: This does not look like a spell file")); goto endFAIL; } ! c = getc(fd); // if (c < VIMSPELLVERSION) { emsg(_("E771: Old spell file, needs to be updated")); *************** *** 425,435 **** */ for (;;) { ! n = getc(fd); /* or */ if (n == SN_END) break; ! c = getc(fd); /* */ ! len = get4c(fd); /* */ if (len < 0) goto truncerr; --- 425,435 ---- */ for (;;) { ! n = getc(fd); // or if (n == SN_END) break; ! c = getc(fd); // ! len = get4c(fd); // if (len < 0) goto truncerr; *************** *** 437,443 **** switch (n) { case SN_INFO: ! lp->sl_info = read_string(fd, len); /* */ if (lp->sl_info == NULL) goto endFAIL; break; --- 437,443 ---- switch (n) { case SN_INFO: ! lp->sl_info = read_string(fd, len); // if (lp->sl_info == NULL) goto endFAIL; break; *************** *** 451,457 **** break; case SN_MIDWORD: ! lp->sl_midword = read_string(fd, len); /* */ if (lp->sl_midword == NULL) goto endFAIL; break; --- 451,457 ---- break; case SN_MIDWORD: ! lp->sl_midword = read_string(fd, len); // if (lp->sl_midword == NULL) goto endFAIL; break; *************** *** 477,483 **** break; case SN_MAP: ! p = read_string(fd, len); /* */ if (p == NULL) goto endFAIL; set_map_str(lp, p); --- 477,483 ---- break; case SN_MAP: ! p = read_string(fd, len); // if (p == NULL) goto endFAIL; set_map_str(lp, p); *************** *** 489,495 **** break; case SN_SUGFILE: ! lp->sl_sugtime = get8ctime(fd); /* */ break; case SN_NOSPLITSUGS: --- 489,495 ---- break; case SN_SUGFILE: ! lp->sl_sugtime = get8ctime(fd); // break; case SN_NOSPLITSUGS: *************** *** 509,515 **** break; case SN_SYLLABLE: ! lp->sl_syllable = read_string(fd, len); /* */ if (lp->sl_syllable == NULL) goto endFAIL; if (init_syl_tab(lp) == FAIL) --- 509,515 ---- break; case SN_SYLLABLE: ! lp->sl_syllable = read_string(fd, len); // if (lp->sl_syllable == NULL) goto endFAIL; if (init_syl_tab(lp) == FAIL) *************** *** 517,524 **** break; default: ! /* Unsupported section. When it's required give an error ! * message. When it's not required skip the contents. */ if (c & SNF_REQUIRED) { emsg(_("E770: Unsupported section in spell file")); --- 517,524 ---- break; default: ! // Unsupported section. When it's required give an error ! // message. When it's not required skip the contents. if (c & SNF_REQUIRED) { emsg(_("E770: Unsupported section in spell file")); *************** *** 545,567 **** goto endFAIL; } ! /* */ res = spell_read_tree(fd, &lp->sl_fbyts, &lp->sl_fidxs, FALSE, 0); if (res != 0) goto someerror; ! /* */ res = spell_read_tree(fd, &lp->sl_kbyts, &lp->sl_kidxs, FALSE, 0); if (res != 0) goto someerror; ! /* */ res = spell_read_tree(fd, &lp->sl_pbyts, &lp->sl_pidxs, TRUE, lp->sl_prefixcnt); if (res != 0) goto someerror; ! /* For a new file link it in the list of spell files. */ if (old_lp == NULL && lang != NULL) { lp->sl_next = first_lang; --- 545,567 ---- goto endFAIL; } ! // res = spell_read_tree(fd, &lp->sl_fbyts, &lp->sl_fidxs, FALSE, 0); if (res != 0) goto someerror; ! // res = spell_read_tree(fd, &lp->sl_kbyts, &lp->sl_kidxs, FALSE, 0); if (res != 0) goto someerror; ! // res = spell_read_tree(fd, &lp->sl_pbyts, &lp->sl_pidxs, TRUE, lp->sl_prefixcnt); if (res != 0) goto someerror; ! // For a new file link it in the list of spell files. if (old_lp == NULL && lang != NULL) { lp->sl_next = first_lang; *************** *** 572,578 **** endFAIL: if (lang != NULL) ! /* truncating the name signals the error to spell_load_lang() */ *lang = NUL; if (lp != NULL && old_lp == NULL) slang_free(lp); --- 572,578 ---- endFAIL: if (lang != NULL) ! // truncating the name signals the error to spell_load_lang() *lang = NUL; if (lp != NULL && old_lp == NULL) slang_free(lp); *************** *** 609,615 **** { if (curi[depth] > byts[arridx[depth]]) { ! /* Done all bytes at this node, go up one level. */ idxs[arridx[depth]] = wordcount[depth]; if (depth > 0) wordcount[depth - 1] += wordcount[depth]; --- 609,615 ---- { if (curi[depth] > byts[arridx[depth]]) { ! // Done all bytes at this node, go up one level. idxs[arridx[depth]] = wordcount[depth]; if (depth > 0) wordcount[depth - 1] += wordcount[depth]; *************** *** 619,636 **** } else { ! /* Do one more byte at this node. */ n = arridx[depth] + curi[depth]; ++curi[depth]; c = byts[n]; if (c == 0) { ! /* End of word, count it. */ ++wordcount[depth]; ! /* Skip over any other NUL bytes (same word with different ! * flags). */ while (byts[n + 1] == 0) { ++n; --- 619,636 ---- } else { ! // Do one more byte at this node. n = arridx[depth] + curi[depth]; ++curi[depth]; c = byts[n]; if (c == 0) { ! // End of word, count it. ++wordcount[depth]; ! // Skip over any other NUL bytes (same word with different ! // flags). while (byts[n + 1] == 0) { ++n; *************** *** 639,645 **** } else { ! /* Normal char, go one level deeper to count the words. */ ++depth; arridx[depth] = idxs[n]; curi[depth] = 1; --- 639,645 ---- } else { ! // Normal char, go one level deeper to count the words. ++depth; arridx[depth] = idxs[n]; curi[depth] = 1; *************** *** 668,683 **** garray_T ga; int c; ! /* Do this for all languages that support sound folding. */ for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) { lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); slang = lp->lp_slang; if (slang->sl_sugtime != 0 && !slang->sl_sugloaded) { ! /* Change ".spl" to ".sug" and open the file. When the file isn't ! * found silently skip it. Do set "sl_sugloaded" so that we ! * don't try again and again. */ slang->sl_sugloaded = TRUE; dotp = vim_strrchr(slang->sl_fname, '.'); --- 668,683 ---- garray_T ga; int c; ! // Do this for all languages that support sound folding. for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) { lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); slang = lp->lp_slang; if (slang->sl_sugtime != 0 && !slang->sl_sugloaded) { ! // Change ".spl" to ".sug" and open the file. When the file isn't ! // found silently skip it. Do set "sl_sugloaded" so that we ! // don't try again and again. slang->sl_sugloaded = TRUE; dotp = vim_strrchr(slang->sl_fname, '.'); *************** *** 692,705 **** * : */ for (i = 0; i < VIMSUGMAGICL; ++i) ! buf[i] = getc(fd); /* */ if (STRNCMP(buf, VIMSUGMAGIC, VIMSUGMAGICL) != 0) { semsg(_("E778: This does not look like a .sug file: %s"), slang->sl_fname); goto nextone; } ! c = getc(fd); /* */ if (c < VIMSUGVERSION) { semsg(_("E779: Old .sug file, needs to be updated: %s"), --- 692,705 ---- * : */ for (i = 0; i < VIMSUGMAGICL; ++i) ! buf[i] = getc(fd); // if (STRNCMP(buf, VIMSUGMAGIC, VIMSUGMAGICL) != 0) { semsg(_("E778: This does not look like a .sug file: %s"), slang->sl_fname); goto nextone; } ! c = getc(fd); // if (c < VIMSUGVERSION) { semsg(_("E779: Old .sug file, needs to be updated: %s"), *************** *** 713,721 **** goto nextone; } ! /* Check the timestamp, it must be exactly the same as the one in ! * the .spl file. Otherwise the word numbers won't match. */ ! timestamp = get8ctime(fd); /* */ if (timestamp != slang->sl_sugtime) { semsg(_("E781: .sug file doesn't match .spl file: %s"), --- 713,721 ---- goto nextone; } ! // Check the timestamp, it must be exactly the same as the one in ! // the .spl file. Otherwise the word numbers won't match. ! timestamp = get8ctime(fd); // if (timestamp != slang->sl_sugtime) { semsg(_("E781: .sug file doesn't match .spl file: %s"), *************** *** 747,766 **** slang->sl_sugbuf = open_spellbuf(); if (slang->sl_sugbuf == NULL) goto someerror; ! /* */ wcount = get4c(fd); if (wcount < 0) goto someerror; ! /* Read all the wordnr lists into the buffer, one NUL terminated ! * list per line. */ ga_init2(&ga, 1, 100); for (wordnr = 0; wordnr < wcount; ++wordnr) { ga.ga_len = 0; for (;;) { ! c = getc(fd); /* */ if (c < 0 || ga_grow(&ga, 1) == FAIL) goto someerror; ((char_u *)ga.ga_data)[ga.ga_len++] = c; --- 747,766 ---- slang->sl_sugbuf = open_spellbuf(); if (slang->sl_sugbuf == NULL) goto someerror; ! // wcount = get4c(fd); if (wcount < 0) goto someerror; ! // Read all the wordnr lists into the buffer, one NUL terminated ! // list per line. ga_init2(&ga, 1, 100); for (wordnr = 0; wordnr < wcount; ++wordnr) { ga.ga_len = 0; for (;;) { ! c = getc(fd); // if (c < 0 || ga_grow(&ga, 1) == FAIL) goto someerror; ((char_u *)ga.ga_data)[ga.ga_len++] = c; *************** *** 803,809 **** int i; char_u *str; ! /* read the length bytes, MSB first */ for (i = 0; i < cnt_bytes; ++i) cnt = (cnt << 8) + getc(fd); if (cnt < 0) --- 803,809 ---- int i; char_u *str; ! // read the length bytes, MSB first for (i = 0; i < cnt_bytes; ++i) cnt = (cnt << 8) + getc(fd); if (cnt < 0) *************** *** 813,819 **** } *cntp = cnt; if (cnt == 0) ! return NULL; /* nothing to read, return NULL */ str = read_string(fd, cnt); if (str == NULL) --- 813,819 ---- } *cntp = cnt; if (cnt == 0) ! return NULL; // nothing to read, return NULL str = read_string(fd, cnt); if (str == NULL) *************** *** 833,839 **** if (len > MAXREGIONS * 2) return SP_FORMERROR; for (i = 0; i < len; ++i) ! lp->sl_regions[i] = getc(fd); /* */ lp->sl_regions[len] = NUL; return 0; } --- 833,839 ---- if (len > MAXREGIONS * 2) return SP_FORMERROR; for (i = 0; i < len; ++i) ! lp->sl_regions[i] = getc(fd); // lp->sl_regions[len] = NUL; return 0; } *************** *** 850,861 **** char_u *fol; int flagslen, follen; ! /* */ flags = read_cnt_string(fd, 1, &flagslen); if (flagslen < 0) return flagslen; ! /* */ fol = read_cnt_string(fd, 2, &follen); if (follen < 0) { --- 850,861 ---- char_u *fol; int flagslen, follen; ! // flags = read_cnt_string(fd, 1, &flagslen); if (flagslen < 0) return flagslen; ! // fol = read_cnt_string(fd, 2, &follen); if (follen < 0) { *************** *** 863,876 **** return follen; } ! /* Set the word-char flags and fill SPELL_ISUPPER() table. */ if (flags != NULL && fol != NULL) set_spell_charflags(flags, flagslen, fol); vim_free(flags); vim_free(fol); ! /* When is zero then must also be zero. */ if ((flags == NULL) != (fol == NULL)) return SP_FORMERROR; return 0; --- 863,876 ---- return follen; } ! // Set the word-char flags and fill SPELL_ISUPPER() table. if (flags != NULL && fol != NULL) set_spell_charflags(flags, flagslen, fol); vim_free(flags); vim_free(fol); ! // When is zero then must also be zero. if ((flags == NULL) != (fol == NULL)) return SP_FORMERROR; return 0; *************** *** 889,896 **** char_u *p; char_u buf[MAXWLEN + 1]; ! /* ... */ ! cnt = get2c(fd); /* */ if (cnt <= 0) return SP_FORMERROR; --- 889,896 ---- char_u *p; char_u buf[MAXWLEN + 1]; ! // ... ! cnt = get2c(fd); // if (cnt <= 0) return SP_FORMERROR; *************** *** 901,919 **** for (i = 0; i < cnt; ++i) { ! /* : */ ! n = getc(fd); /* */ if (n < 0 || n >= MAXWLEN) return SP_FORMERROR; ! /* When is zero we have an empty condition. Otherwise ! * compile the regexp program used to check for the condition. */ if (n > 0) { ! buf[0] = '^'; /* always match at one position only */ p = buf + 1; while (n-- > 0) ! *p++ = getc(fd); /* */ *p = NUL; lp->sl_prefprog[i] = vim_regcomp(buf, RE_MAGIC + RE_STRING); } --- 901,919 ---- for (i = 0; i < cnt; ++i) { ! // : ! n = getc(fd); // if (n < 0 || n >= MAXWLEN) return SP_FORMERROR; ! // When is zero we have an empty condition. Otherwise ! // compile the regexp program used to check for the condition. if (n > 0) { ! buf[0] = '^'; // always match at one position only p = buf + 1; while (n-- > 0) ! *p++ = getc(fd); // *p = NUL; lp->sl_prefprog[i] = vim_regcomp(buf, RE_MAGIC + RE_STRING); } *************** *** 932,945 **** fromto_T *ftp; int i; ! cnt = get2c(fd); /* */ if (cnt < 0) return SP_TRUNCERROR; if (ga_grow(gap, cnt) == FAIL) return SP_OTHERERROR; ! /* : */ for (; gap->ga_len < cnt; ++gap->ga_len) { ftp = &((fromto_T *)gap->ga_data)[gap->ga_len]; --- 932,945 ---- fromto_T *ftp; int i; ! cnt = get2c(fd); // if (cnt < 0) return SP_TRUNCERROR; if (ga_grow(gap, cnt) == FAIL) return SP_OTHERERROR; ! // : for (; gap->ga_len < cnt; ++gap->ga_len) { ftp = &((fromto_T *)gap->ga_data)[gap->ga_len]; *************** *** 958,964 **** } } ! /* Fill the first-index table. */ for (i = 0; i < 256; ++i) first[i] = -1; for (i = 0; i < gap->ga_len; ++i) --- 958,964 ---- } } ! // Fill the first-index table. for (i = 0; i < 256; ++i) first[i] = -1; for (i = 0; i < gap->ga_len; ++i) *************** *** 987,993 **** slang->sl_sofo = FALSE; ! i = getc(fd); /* */ if (i & SAL_F0LLOWUP) slang->sl_followup = TRUE; if (i & SAL_COLLAPSE) --- 987,993 ---- slang->sl_sofo = FALSE; ! i = getc(fd); // if (i & SAL_F0LLOWUP) slang->sl_followup = TRUE; if (i & SAL_COLLAPSE) *************** *** 995,1001 **** if (i & SAL_REM_ACCENTS) slang->sl_rem_accents = TRUE; ! cnt = get2c(fd); /* */ if (cnt < 0) return SP_TRUNCERROR; --- 995,1001 ---- if (i & SAL_REM_ACCENTS) slang->sl_rem_accents = TRUE; ! cnt = get2c(fd); // if (cnt < 0) return SP_TRUNCERROR; *************** *** 1004,1024 **** if (ga_grow(gap, cnt + 1) == FAIL) return SP_OTHERERROR; ! /* : */ for (; gap->ga_len < cnt; ++gap->ga_len) { smp = &((salitem_T *)gap->ga_data)[gap->ga_len]; ! ccnt = getc(fd); /* */ if (ccnt < 0) return SP_TRUNCERROR; if ((p = alloc(ccnt + 2)) == NULL) return SP_OTHERERROR; smp->sm_lead = p; ! /* Read up to the first special char into sm_lead. */ for (i = 0; i < ccnt; ++i) { ! c = getc(fd); /* */ if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL) break; *p++ = c; --- 1004,1024 ---- if (ga_grow(gap, cnt + 1) == FAIL) return SP_OTHERERROR; ! // : for (; gap->ga_len < cnt; ++gap->ga_len) { smp = &((salitem_T *)gap->ga_data)[gap->ga_len]; ! ccnt = getc(fd); // if (ccnt < 0) return SP_TRUNCERROR; if ((p = alloc(ccnt + 2)) == NULL) return SP_OTHERERROR; smp->sm_lead = p; ! // Read up to the first special char into sm_lead. for (i = 0; i < ccnt; ++i) { ! c = getc(fd); // if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL) break; *p++ = c; *************** *** 1026,1038 **** smp->sm_leadlen = (int)(p - smp->sm_lead); *p++ = NUL; ! /* Put (abc) chars in sm_oneof, if any. */ if (c == '(') { smp->sm_oneof = p; for (++i; i < ccnt; ++i) { ! c = getc(fd); /* */ if (c == ')') break; *p++ = c; --- 1026,1038 ---- smp->sm_leadlen = (int)(p - smp->sm_lead); *p++ = NUL; ! // Put (abc) chars in sm_oneof, if any. if (c == '(') { smp->sm_oneof = p; for (++i; i < ccnt; ++i) { ! c = getc(fd); // if (c == ')') break; *p++ = c; *************** *** 1044,1059 **** else smp->sm_oneof = NULL; ! /* Any following chars go in sm_rules. */ smp->sm_rules = p; if (i < ccnt) ! /* store the char we got while checking for end of sm_lead */ *p++ = c; for (++i; i < ccnt; ++i) ! *p++ = getc(fd); /* */ *p++ = NUL; ! /* */ smp->sm_to = read_cnt_string(fd, 1, &ccnt); if (ccnt < 0) { --- 1044,1059 ---- else smp->sm_oneof = NULL; ! // Any following chars go in sm_rules. smp->sm_rules = p; if (i < ccnt) ! // store the char we got while checking for end of sm_lead *p++ = c; for (++i; i < ccnt; ++i) ! *p++ = getc(fd); // *p++ = NUL; ! // smp->sm_to = read_cnt_string(fd, 1, &ccnt); if (ccnt < 0) { *************** *** 1063,1069 **** if (has_mbyte) { ! /* convert the multi-byte strings to wide char strings */ smp->sm_lead_w = mb_str2wide(smp->sm_lead); smp->sm_leadlen = mb_charlen(smp->sm_lead); if (smp->sm_oneof == NULL) --- 1063,1069 ---- if (has_mbyte) { ! // convert the multi-byte strings to wide char strings smp->sm_lead_w = mb_str2wide(smp->sm_lead); smp->sm_leadlen = mb_charlen(smp->sm_lead); if (smp->sm_oneof == NULL) *************** *** 1090,1097 **** if (gap->ga_len > 0) { ! /* Add one extra entry to mark the end with an empty sm_lead. Avoids ! * that we need to check the index every time. */ smp = &((salitem_T *)gap->ga_data)[gap->ga_len]; if ((p = alloc(1)) == NULL) return SP_OTHERERROR; --- 1090,1097 ---- if (gap->ga_len > 0) { ! // Add one extra entry to mark the end with an empty sm_lead. Avoids ! // that we need to check the index every time. smp = &((salitem_T *)gap->ga_data)[gap->ga_len]; if ((p = alloc(1)) == NULL) return SP_OTHERERROR; *************** *** 1111,1117 **** ++gap->ga_len; } ! /* Fill the first-index table. */ set_sal_first(slang); return 0; --- 1111,1117 ---- ++gap->ga_len; } ! // Fill the first-index table. set_sal_first(slang); return 0; *************** *** 1131,1137 **** while (done < len) { ! /* Read one word at a time. */ for (i = 0; ; ++i) { c = getc(fd); --- 1131,1137 ---- while (done < len) { ! // Read one word at a time. for (i = 0; ; ++i) { c = getc(fd); *************** *** 1144,1150 **** return SP_FORMERROR; } ! /* Init the count to 10. */ count_common_word(lp, word, -1, 10); done += i + 1; } --- 1144,1150 ---- return SP_FORMERROR; } ! // Init the count to 10. count_common_word(lp, word, -1, 10); done += i + 1; } *************** *** 1164,1175 **** slang->sl_sofo = TRUE; ! /* */ from = read_cnt_string(fd, 2, &cnt); if (cnt < 0) return cnt; ! /* */ to = read_cnt_string(fd, 2, &cnt); if (cnt < 0) { --- 1164,1175 ---- slang->sl_sofo = TRUE; ! // from = read_cnt_string(fd, 2, &cnt); if (cnt < 0) return cnt; ! // to = read_cnt_string(fd, 2, &cnt); if (cnt < 0) { *************** *** 1177,1187 **** return cnt; } ! /* Store the info in slang->sl_sal and/or slang->sl_sal_first. */ if (from != NULL && to != NULL) res = set_sofo(slang, from, to); else if (from != NULL || to != NULL) ! res = SP_FORMERROR; /* only one of two strings is an error */ else res = 0; --- 1177,1187 ---- return cnt; } ! // Store the info in slang->sl_sal and/or slang->sl_sal_first. if (from != NULL && to != NULL) res = set_sofo(slang, from, to); else if (from != NULL || to != NULL) ! res = SP_FORMERROR; // only one of two strings is an error else res = 0; *************** *** 1210,1247 **** garray_T *gap; if (todo < 2) ! return SP_FORMERROR; /* need at least two bytes */ --todo; ! c = getc(fd); /* */ if (c < 2) c = MAXWLEN; slang->sl_compmax = c; --todo; ! c = getc(fd); /* */ if (c < 1) c = 0; slang->sl_compminlen = c; --todo; ! c = getc(fd); /* */ if (c < 1) c = MAXWLEN; slang->sl_compsylmax = c; ! c = getc(fd); /* */ if (c != 0) ! ungetc(c, fd); /* be backwards compatible with Vim 7.0b */ else { --todo; ! c = getc(fd); /* only use the lower byte for now */ --todo; slang->sl_compoptions = c; gap = &slang->sl_comppat; ! c = get2c(fd); /* */ todo -= 2; ga_init2(gap, sizeof(char_u *), c); if (ga_grow(gap, c) == OK) --- 1210,1247 ---- garray_T *gap; if (todo < 2) ! return SP_FORMERROR; // need at least two bytes --todo; ! c = getc(fd); // if (c < 2) c = MAXWLEN; slang->sl_compmax = c; --todo; ! c = getc(fd); // if (c < 1) c = 0; slang->sl_compminlen = c; --todo; ! c = getc(fd); // if (c < 1) c = MAXWLEN; slang->sl_compsylmax = c; ! c = getc(fd); // if (c != 0) ! ungetc(c, fd); // be backwards compatible with Vim 7.0b else { --todo; ! c = getc(fd); // only use the lower byte for now --todo; slang->sl_compoptions = c; gap = &slang->sl_comppat; ! c = get2c(fd); // todo -= 2; ga_init2(gap, sizeof(char_u *), c); if (ga_grow(gap, c) == OK) *************** *** 1249,1255 **** { ((char_u **)(gap->ga_data))[gap->ga_len++] = read_cnt_string(fd, 1, &cnt); ! /* */ if (cnt < 0) return cnt; todo -= cnt + 1; --- 1249,1255 ---- { ((char_u **)(gap->ga_data))[gap->ga_len++] = read_cnt_string(fd, 1, &cnt); ! // if (cnt < 0) return cnt; todo -= cnt + 1; *************** *** 1258,1267 **** if (todo < 0) return SP_FORMERROR; ! /* Turn the COMPOUNDRULE items into a regexp pattern: ! * "a[bc]/a*b+" -> "^\(a[bc]\|a*b\+\)$". ! * Inserting backslashes may double the length, "^\(\)$" is 7 bytes. ! * Conversion to utf-8 may double the size. */ c = todo * 2 + 7; if (enc_utf8) c += todo * 2; --- 1258,1267 ---- if (todo < 0) return SP_FORMERROR; ! // Turn the COMPOUNDRULE items into a regexp pattern: ! // "a[bc]/a*b+" -> "^\(a[bc]\|a*b\+\)$". ! // Inserting backslashes may double the length, "^\(\)$" is 7 bytes. ! // Conversion to utf-8 may double the size. c = todo * 2 + 7; if (enc_utf8) c += todo * 2; *************** *** 1269,1276 **** if (pat == NULL) return SP_OTHERERROR; ! /* We also need a list of all flags that can appear at the start and one ! * for all flags. */ cp = alloc(todo + 1); if (cp == NULL) { --- 1269,1276 ---- if (pat == NULL) return SP_OTHERERROR; ! // We also need a list of all flags that can appear at the start and one ! // for all flags. cp = alloc(todo + 1); if (cp == NULL) { *************** *** 1289,1297 **** slang->sl_compallflags = ap; *ap = NUL; ! /* And a list of all patterns in their original form, for checking whether ! * compounding may work in match_compoundrule(). This is freed when we ! * encounter a wildcard, the check doesn't work then. */ crp = alloc(todo + 1); slang->sl_comprules = crp; --- 1289,1297 ---- slang->sl_compallflags = ap; *ap = NUL; ! // And a list of all patterns in their original form, for checking whether ! // compounding may work in match_compoundrule(). This is freed when we ! // encounter a wildcard, the check doesn't work then. crp = alloc(todo + 1); slang->sl_comprules = crp; *************** *** 1303,1316 **** atstart = 1; while (todo-- > 0) { ! c = getc(fd); /* */ if (c == EOF) { vim_free(pat); return SP_TRUNCERROR; } ! /* Add all flags to "sl_compallflags". */ if (vim_strchr((char_u *)"?*+[]/", c) == NULL && !byte_in_str(slang->sl_compallflags, c)) { --- 1303,1316 ---- atstart = 1; while (todo-- > 0) { ! c = getc(fd); // if (c == EOF) { vim_free(pat); return SP_TRUNCERROR; } ! // Add all flags to "sl_compallflags". if (vim_strchr((char_u *)"?*+[]/", c) == NULL && !byte_in_str(slang->sl_compallflags, c)) { *************** *** 1320,1327 **** if (atstart != 0) { ! /* At start of item: copy flags to "sl_compstartflags". For a ! * [abc] item set "atstart" to 2 and copy up to the ']'. */ if (c == '[') atstart = 2; else if (c == ']') --- 1320,1327 ---- if (atstart != 0) { ! // At start of item: copy flags to "sl_compstartflags". For a ! // [abc] item set "atstart" to 2 and copy up to the ']'. if (c == '[') atstart = 2; else if (c == ']') *************** *** 1338,1344 **** } } ! /* Copy flag to "sl_comprules", unless we run into a wildcard. */ if (crp != NULL) { if (c == '?' || c == '+' || c == '*') --- 1338,1344 ---- } } ! // Copy flag to "sl_comprules", unless we run into a wildcard. if (crp != NULL) { if (c == '?' || c == '+' || c == '*') *************** *** 1350,1365 **** *crp++ = c; } ! if (c == '/') /* slash separates two items */ { *pp++ = '\\'; *pp++ = '|'; atstart = 1; } ! else /* normal char, "[abc]" and '*' are copied as-is */ { if (c == '?' || c == '+' || c == '~') ! *pp++ = '\\'; /* "a?" becomes "a\?", "a+" becomes "a\+" */ if (enc_utf8) pp += mb_char2bytes(c, pp); else --- 1350,1365 ---- *crp++ = c; } ! if (c == '/') // slash separates two items { *pp++ = '\\'; *pp++ = '|'; atstart = 1; } ! else // normal char, "[abc]" and '*' are copied as-is { if (c == '?' || c == '+' || c == '~') ! *pp++ = '\\'; // "a?" becomes "a\?", "a+" becomes "a\+" if (enc_utf8) pp += mb_char2bytes(c, pp); else *************** *** 1400,1409 **** if (has_mbyte) { ! /* Use "sl_sal" as an array with 256 pointers to a list of wide ! * characters. The index is the low byte of the character. ! * The list contains from-to pairs with a terminating NUL. ! * sl_sal_first[] is used for latin1 "from" characters. */ gap = &lp->sl_sal; ga_init2(gap, sizeof(int *), 1); if (ga_grow(gap, 256) == FAIL) --- 1400,1409 ---- if (has_mbyte) { ! // Use "sl_sal" as an array with 256 pointers to a list of wide ! // characters. The index is the low byte of the character. ! // The list contains from-to pairs with a terminating NUL. ! // sl_sal_first[] is used for latin1 "from" characters. gap = &lp->sl_sal; ga_init2(gap, sizeof(int *), 1); if (ga_grow(gap, 256) == FAIL) *************** *** 1411,1418 **** vim_memset(gap->ga_data, 0, sizeof(int *) * 256); gap->ga_len = 256; ! /* First count the number of items for each list. Temporarily use ! * sl_sal_first[] for this. */ for (p = from, s = to; *p != NUL && *s != NUL; ) { c = mb_cptr2char_adv(&p); --- 1411,1418 ---- vim_memset(gap->ga_data, 0, sizeof(int *) * 256); gap->ga_len = 256; ! // First count the number of items for each list. Temporarily use ! // sl_sal_first[] for this. for (p = from, s = to; *p != NUL && *s != NUL; ) { c = mb_cptr2char_adv(&p); *************** *** 1420,1429 **** if (c >= 256) ++lp->sl_sal_first[c & 0xff]; } ! if (*p != NUL || *s != NUL) /* lengths differ */ return SP_FORMERROR; ! /* Allocate the lists. */ for (i = 0; i < 256; ++i) if (lp->sl_sal_first[i] > 0) { --- 1420,1429 ---- if (c >= 256) ++lp->sl_sal_first[c & 0xff]; } ! if (*p != NUL || *s != NUL) // lengths differ return SP_FORMERROR; ! // Allocate the lists. for (i = 0; i < 256; ++i) if (lp->sl_sal_first[i] > 0) { *************** *** 1434,1441 **** *(int *)p = 0; } ! /* Put the characters up to 255 in sl_sal_first[] the rest in a sl_sal ! * list. */ vim_memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256); for (p = from, s = to; *p != NUL && *s != NUL; ) { --- 1434,1441 ---- *(int *)p = 0; } ! // Put the characters up to 255 in sl_sal_first[] the rest in a sl_sal ! // list. vim_memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256); for (p = from, s = to; *p != NUL && *s != NUL; ) { *************** *** 1443,1471 **** i = mb_cptr2char_adv(&s); if (c >= 256) { ! /* Append the from-to chars at the end of the list with ! * the low byte. */ inp = ((int **)gap->ga_data)[c & 0xff]; while (*inp != 0) ++inp; ! *inp++ = c; /* from char */ ! *inp++ = i; /* to char */ ! *inp++ = NUL; /* NUL at the end */ } else ! /* mapping byte to char is done in sl_sal_first[] */ lp->sl_sal_first[c] = i; } } else { ! /* mapping bytes to bytes is done in sl_sal_first[] */ if (STRLEN(from) != STRLEN(to)) return SP_FORMERROR; for (i = 0; to[i] != NUL; ++i) lp->sl_sal_first[from[i]] = to[i]; ! lp->sl_sal.ga_len = 1; /* indicates we have soundfolding */ } return 0; --- 1443,1471 ---- i = mb_cptr2char_adv(&s); if (c >= 256) { ! // Append the from-to chars at the end of the list with ! // the low byte. inp = ((int **)gap->ga_data)[c & 0xff]; while (*inp != 0) ++inp; ! *inp++ = c; // from char ! *inp++ = i; // to char ! *inp++ = NUL; // NUL at the end } else ! // mapping byte to char is done in sl_sal_first[] lp->sl_sal_first[c] = i; } } else { ! // mapping bytes to bytes is done in sl_sal_first[] if (STRLEN(from) != STRLEN(to)) return SP_FORMERROR; for (i = 0; to[i] != NUL; ++i) lp->sl_sal_first[from[i]] = to[i]; ! lp->sl_sal.ga_len = 1; // indicates we have soundfolding } return 0; *************** *** 1490,1498 **** for (i = 0; i < gap->ga_len; ++i) { if (has_mbyte) ! /* Use the lowest byte of the first character. For latin1 it's ! * the character, for other encodings it should differ for most ! * characters. */ c = *smp[i].sm_lead_w & 0xff; else c = *smp[i].sm_lead; --- 1490,1498 ---- for (i = 0; i < gap->ga_len; ++i) { if (has_mbyte) ! // Use the lowest byte of the first character. For latin1 it's ! // the character, for other encodings it should differ for most ! // characters. c = *smp[i].sm_lead_w & 0xff; else c = *smp[i].sm_lead; *************** *** 1503,1514 **** { int n; ! /* Make sure all entries with this byte are following each ! * other. Move the ones that are in the wrong position. Do ! * keep the same ordering! */ while (i + 1 < gap->ga_len && (*smp[i + 1].sm_lead_w & 0xff) == c) ! /* Skip over entry with same index byte. */ ++i; for (n = 1; i + n < gap->ga_len; ++n) --- 1503,1514 ---- { int n; ! // Make sure all entries with this byte are following each ! // other. Move the ones that are in the wrong position. Do ! // keep the same ordering! while (i + 1 < gap->ga_len && (*smp[i + 1].sm_lead_w & 0xff) == c) ! // Skip over entry with same index byte. ++i; for (n = 1; i + n < gap->ga_len; ++n) *************** *** 1516,1523 **** { salitem_T tsal; ! /* Move entry with same index byte after the entries ! * we already found. */ ++i; --n; tsal = smp[i + n]; --- 1516,1523 ---- { salitem_T tsal; ! // Move entry with same index byte after the entries ! // we already found. ++i; --n; tsal = smp[i + n]; *************** *** 1562,1598 **** FILE *fd, char_u **bytsp, idx_T **idxsp, ! int prefixtree, /* TRUE for the prefix tree */ ! int prefixcnt) /* when "prefixtree" is TRUE: prefix count */ { long len; int idx; char_u *bp; idx_T *ip; ! /* The tree size was computed when writing the file, so that we can ! * allocate it as one long block. */ len = get4c(fd); if (len < 0) return SP_TRUNCERROR; if (len >= LONG_MAX / (long)sizeof(int)) ! /* Invalid length, multiply with sizeof(int) would overflow. */ return SP_FORMERROR; if (len > 0) { ! /* Allocate the byte array. */ bp = alloc(len); if (bp == NULL) return SP_OTHERERROR; *bytsp = bp; ! /* Allocate the index array. */ ip = lalloc_clear(len * sizeof(int), TRUE); if (ip == NULL) return SP_OTHERERROR; *idxsp = ip; ! /* Recursively read the tree and store it in the array. */ idx = read_tree_node(fd, bp, ip, len, 0, prefixtree, prefixcnt); if (idx < 0) return idx; --- 1562,1598 ---- FILE *fd, char_u **bytsp, idx_T **idxsp, ! int prefixtree, // TRUE for the prefix tree ! int prefixcnt) // when "prefixtree" is TRUE: prefix count { long len; int idx; char_u *bp; idx_T *ip; ! // The tree size was computed when writing the file, so that we can ! // allocate it as one long block. len = get4c(fd); if (len < 0) return SP_TRUNCERROR; if (len >= LONG_MAX / (long)sizeof(int)) ! // Invalid length, multiply with sizeof(int) would overflow. return SP_FORMERROR; if (len > 0) { ! // Allocate the byte array. bp = alloc(len); if (bp == NULL) return SP_OTHERERROR; *bytsp = bp; ! // Allocate the index array. ip = lalloc_clear(len * sizeof(int), TRUE); if (ip == NULL) return SP_OTHERERROR; *idxsp = ip; ! // Recursively read the tree and store it in the array. idx = read_tree_node(fd, bp, ip, len, 0, prefixtree, prefixcnt); if (idx < 0) return idx; *************** *** 1615,1624 **** FILE *fd, char_u *byts, idx_T *idxs, ! int maxidx, /* size of arrays */ ! idx_T startidx, /* current index in "byts" and "idxs" */ ! int prefixtree, /* TRUE for reading PREFIXTREE */ ! int maxprefcondnr) /* maximum for */ { int len; int i; --- 1615,1624 ---- FILE *fd, char_u *byts, idx_T *idxs, ! int maxidx, // size of arrays ! idx_T startidx, // current index in "byts" and "idxs" ! int prefixtree, // TRUE for reading PREFIXTREE ! int maxprefcondnr) // maximum for { int len; int i; *************** *** 1628,1634 **** int c2; #define SHARED_MASK 0x8000000 ! len = getc(fd); /* */ if (len <= 0) return SP_TRUNCERROR; --- 1628,1634 ---- int c2; #define SHARED_MASK 0x8000000 ! len = getc(fd); // if (len <= 0) return SP_TRUNCERROR; *************** *** 1636,1652 **** return SP_FORMERROR; byts[idx++] = len; ! /* Read the byte values, flag/region bytes and shared indexes. */ for (i = 1; i <= len; ++i) { ! c = getc(fd); /* */ if (c < 0) return SP_TRUNCERROR; if (c <= BY_SPECIAL) { if (c == BY_NOFLAGS && !prefixtree) { ! /* No flags, all regions. */ idxs[idx] = 0; c = 0; } --- 1636,1652 ---- return SP_FORMERROR; byts[idx++] = len; ! // Read the byte values, flag/region bytes and shared indexes. for (i = 1; i <= len; ++i) { ! c = getc(fd); // if (c < 0) return SP_TRUNCERROR; if (c <= BY_SPECIAL) { if (c == BY_NOFLAGS && !prefixtree) { ! // No flags, all regions. idxs[idx] = 0; c = 0; } *************** *** 1654,1709 **** { if (prefixtree) { ! /* Read the optional pflags byte, the prefix ID and the ! * condition nr. In idxs[] store the prefix ID in the low ! * byte, the condition index shifted up 8 bits, the flags ! * shifted up 24 bits. */ if (c == BY_FLAGS) ! c = getc(fd) << 24; /* */ else c = 0; ! c |= getc(fd); /* */ ! n = get2c(fd); /* */ if (n >= maxprefcondnr) return SP_FORMERROR; c |= (n << 8); } ! else /* c must be BY_FLAGS or BY_FLAGS2 */ { ! /* Read flags and optional region and prefix ID. In ! * idxs[] the flags go in the low two bytes, region above ! * that and prefix ID above the region. */ c2 = c; ! c = getc(fd); /* */ if (c2 == BY_FLAGS2) ! c = (getc(fd) << 8) + c; /* */ if (c & WF_REGION) ! c = (getc(fd) << 16) + c; /* */ if (c & WF_AFX) ! c = (getc(fd) << 24) + c; /* */ } idxs[idx] = c; c = 0; } ! else /* c == BY_INDEX */ { ! /* */ n = get3c(fd); if (n < 0 || n >= maxidx) return SP_FORMERROR; idxs[idx] = n + SHARED_MASK; ! c = getc(fd); /* */ } } byts[idx++] = c; } ! /* Recursively read the children for non-shared siblings. ! * Skip the end-of-word ones (zero byte value) and the shared ones (and ! * remove SHARED_MASK) */ for (i = 1; i <= len; ++i) if (byts[startidx + i] != 0) { --- 1654,1709 ---- { if (prefixtree) { ! // Read the optional pflags byte, the prefix ID and the ! // condition nr. In idxs[] store the prefix ID in the low ! // byte, the condition index shifted up 8 bits, the flags ! // shifted up 24 bits. if (c == BY_FLAGS) ! c = getc(fd) << 24; // else c = 0; ! c |= getc(fd); // ! n = get2c(fd); // if (n >= maxprefcondnr) return SP_FORMERROR; c |= (n << 8); } ! else // c must be BY_FLAGS or BY_FLAGS2 { ! // Read flags and optional region and prefix ID. In ! // idxs[] the flags go in the low two bytes, region above ! // that and prefix ID above the region. c2 = c; ! c = getc(fd); // if (c2 == BY_FLAGS2) ! c = (getc(fd) << 8) + c; // if (c & WF_REGION) ! c = (getc(fd) << 16) + c; // if (c & WF_AFX) ! c = (getc(fd) << 24) + c; // } idxs[idx] = c; c = 0; } ! else // c == BY_INDEX { ! // n = get3c(fd); if (n < 0 || n >= maxidx) return SP_FORMERROR; idxs[idx] = n + SHARED_MASK; ! c = getc(fd); // } } byts[idx++] = c; } ! // Recursively read the children for non-shared siblings. ! // Skip the end-of-word ones (zero byte value) and the shared ones (and ! // remove SHARED_MASK) for (i = 1; i <= len; ++i) if (byts[startidx + i] != 0) { *************** *** 1728,1734 **** static void spell_reload_one( char_u *fname, ! int added_word) /* invoked through "zg" */ { slang_T *slang; int didit = FALSE; --- 1728,1734 ---- static void spell_reload_one( char_u *fname, ! int added_word) // invoked through "zg" { slang_T *slang; int didit = FALSE; *************** *** 1739,1753 **** { slang_clear(slang); if (spell_load_file(fname, NULL, slang, FALSE) == NULL) ! /* reloading failed, clear the language */ slang_clear(slang); redraw_all_later(SOME_VALID); didit = TRUE; } } ! /* When "zg" was used and the file wasn't loaded yet, should redo ! * 'spelllang' to load it now. */ if (added_word && !didit) did_set_spelllang(curwin); } --- 1739,1753 ---- { slang_clear(slang); if (spell_load_file(fname, NULL, slang, FALSE) == NULL) ! // reloading failed, clear the language slang_clear(slang); redraw_all_later(SOME_VALID); didit = TRUE; } } ! // When "zg" was used and the file wasn't loaded yet, should redo ! // 'spelllang' to load it now. if (added_word && !didit) did_set_spelllang(curwin); } *************** *** 1757,1829 **** * Functions for ":mkspell". */ ! #define MAXLINELEN 500 /* Maximum length in bytes of a line in a .aff ! and .dic file. */ /* * Main structure to store the contents of a ".aff" file. */ typedef struct afffile_S { ! char_u *af_enc; /* "SET", normalized, alloc'ed string or NULL */ ! int af_flagtype; /* AFT_CHAR, AFT_LONG, AFT_NUM or AFT_CAPLONG */ ! unsigned af_rare; /* RARE ID for rare word */ ! unsigned af_keepcase; /* KEEPCASE ID for keep-case word */ ! unsigned af_bad; /* BAD ID for banned word */ ! unsigned af_needaffix; /* NEEDAFFIX ID */ ! unsigned af_circumfix; /* CIRCUMFIX ID */ ! unsigned af_needcomp; /* NEEDCOMPOUND ID */ ! unsigned af_comproot; /* COMPOUNDROOT ID */ ! unsigned af_compforbid; /* COMPOUNDFORBIDFLAG ID */ ! unsigned af_comppermit; /* COMPOUNDPERMITFLAG ID */ ! unsigned af_nosuggest; /* NOSUGGEST ID */ ! int af_pfxpostpone; /* postpone prefixes without chop string and ! without flags */ ! int af_ignoreextra; /* IGNOREEXTRA present */ ! hashtab_T af_pref; /* hashtable for prefixes, affheader_T */ ! hashtab_T af_suff; /* hashtable for suffixes, affheader_T */ ! hashtab_T af_comp; /* hashtable for compound flags, compitem_T */ } afffile_T; ! #define AFT_CHAR 0 /* flags are one character */ ! #define AFT_LONG 1 /* flags are two characters */ ! #define AFT_CAPLONG 2 /* flags are one or two characters */ ! #define AFT_NUM 3 /* flags are numbers, comma separated */ typedef struct affentry_S affentry_T; ! /* Affix entry from ".aff" file. Used for prefixes and suffixes. */ struct affentry_S { ! affentry_T *ae_next; /* next affix with same name/number */ ! char_u *ae_chop; /* text to chop off basic word (can be NULL) */ ! char_u *ae_add; /* text to add to basic word (can be NULL) */ ! char_u *ae_flags; /* flags on the affix (can be NULL) */ ! char_u *ae_cond; /* condition (NULL for ".") */ ! regprog_T *ae_prog; /* regexp program for ae_cond or NULL */ ! char ae_compforbid; /* COMPOUNDFORBIDFLAG found */ ! char ae_comppermit; /* COMPOUNDPERMITFLAG found */ }; ! #define AH_KEY_LEN 17 /* 2 x 8 bytes + NUL */ ! /* Affix header from ".aff" file. Used for af_pref and af_suff. */ typedef struct affheader_S { ! char_u ah_key[AH_KEY_LEN]; /* key for hashtab == name of affix */ ! unsigned ah_flag; /* affix name as number, uses "af_flagtype" */ ! int ah_newID; /* prefix ID after renumbering; 0 if not used */ ! int ah_combine; /* suffix may combine with prefix */ ! int ah_follows; /* another affix block should be following */ ! affentry_T *ah_first; /* first affix entry */ } affheader_T; #define HI2AH(hi) ((affheader_T *)(hi)->hi_key) ! /* Flag used in compound items. */ typedef struct compitem_S { ! char_u ci_key[AH_KEY_LEN]; /* key for hashtab == name of compound */ ! unsigned ci_flag; /* affix name as number, uses "af_flagtype" */ ! int ci_newID; /* affix ID after renumbering. */ } compitem_T; #define HI2CI(hi) ((compitem_T *)(hi)->hi_key) --- 1757,1829 ---- * Functions for ":mkspell". */ ! #define MAXLINELEN 500 // Maximum length in bytes of a line in a .aff ! // and .dic file. /* * Main structure to store the contents of a ".aff" file. */ typedef struct afffile_S { ! char_u *af_enc; // "SET", normalized, alloc'ed string or NULL ! int af_flagtype; // AFT_CHAR, AFT_LONG, AFT_NUM or AFT_CAPLONG ! unsigned af_rare; // RARE ID for rare word ! unsigned af_keepcase; // KEEPCASE ID for keep-case word ! unsigned af_bad; // BAD ID for banned word ! unsigned af_needaffix; // NEEDAFFIX ID ! unsigned af_circumfix; // CIRCUMFIX ID ! unsigned af_needcomp; // NEEDCOMPOUND ID ! unsigned af_comproot; // COMPOUNDROOT ID ! unsigned af_compforbid; // COMPOUNDFORBIDFLAG ID ! unsigned af_comppermit; // COMPOUNDPERMITFLAG ID ! unsigned af_nosuggest; // NOSUGGEST ID ! int af_pfxpostpone; // postpone prefixes without chop string and ! // without flags ! int af_ignoreextra; // IGNOREEXTRA present ! hashtab_T af_pref; // hashtable for prefixes, affheader_T ! hashtab_T af_suff; // hashtable for suffixes, affheader_T ! hashtab_T af_comp; // hashtable for compound flags, compitem_T } afffile_T; ! #define AFT_CHAR 0 // flags are one character ! #define AFT_LONG 1 // flags are two characters ! #define AFT_CAPLONG 2 // flags are one or two characters ! #define AFT_NUM 3 // flags are numbers, comma separated typedef struct affentry_S affentry_T; ! // Affix entry from ".aff" file. Used for prefixes and suffixes. struct affentry_S { ! affentry_T *ae_next; // next affix with same name/number ! char_u *ae_chop; // text to chop off basic word (can be NULL) ! char_u *ae_add; // text to add to basic word (can be NULL) ! char_u *ae_flags; // flags on the affix (can be NULL) ! char_u *ae_cond; // condition (NULL for ".") ! regprog_T *ae_prog; // regexp program for ae_cond or NULL ! char ae_compforbid; // COMPOUNDFORBIDFLAG found ! char ae_comppermit; // COMPOUNDPERMITFLAG found }; ! #define AH_KEY_LEN 17 // 2 x 8 bytes + NUL ! // Affix header from ".aff" file. Used for af_pref and af_suff. typedef struct affheader_S { ! char_u ah_key[AH_KEY_LEN]; // key for hashtab == name of affix ! unsigned ah_flag; // affix name as number, uses "af_flagtype" ! int ah_newID; // prefix ID after renumbering; 0 if not used ! int ah_combine; // suffix may combine with prefix ! int ah_follows; // another affix block should be following ! affentry_T *ah_first; // first affix entry } affheader_T; #define HI2AH(hi) ((affheader_T *)(hi)->hi_key) ! // Flag used in compound items. typedef struct compitem_S { ! char_u ci_key[AH_KEY_LEN]; // key for hashtab == name of compound ! unsigned ci_flag; // affix name as number, uses "af_flagtype" ! int ci_newID; // affix ID after renumbering. } compitem_T; #define HI2CI(hi) ((compitem_T *)(hi)->hi_key) *************** *** 1836,1848 **** * "sb_data" is correct for systems where pointers must be aligned on * pointer-size boundaries and sizeof(pointer) > sizeof(int) (e.g., Sparc). */ ! #define SBLOCKSIZE 16000 /* size of sb_data */ typedef struct sblock_S sblock_T; struct sblock_S { ! int sb_used; /* nr of bytes already in use */ ! sblock_T *sb_next; /* next block in list */ ! char_u sb_data[1]; /* data, actually longer */ }; /* --- 1836,1848 ---- * "sb_data" is correct for systems where pointers must be aligned on * pointer-size boundaries and sizeof(pointer) > sizeof(int) (e.g., Sparc). */ ! #define SBLOCKSIZE 16000 // size of sb_data typedef struct sblock_S sblock_T; struct sblock_S { ! int sb_used; // nr of bytes already in use ! sblock_T *sb_next; // next block in list ! char_u sb_data[1]; // data, actually longer }; /* *************** *** 1851,1890 **** typedef struct wordnode_S wordnode_T; struct wordnode_S { ! union /* shared to save space */ { ! char_u hashkey[6]; /* the hash key, only used while compressing */ ! int index; /* index in written nodes (valid after first ! round) */ } wn_u1; ! union /* shared to save space */ { ! wordnode_T *next; /* next node with same hash key */ ! wordnode_T *wnode; /* parent node that will write this node */ } wn_u2; ! wordnode_T *wn_child; /* child (next byte in word) */ ! wordnode_T *wn_sibling; /* next sibling (alternate byte in word, ! always sorted) */ ! int wn_refs; /* Nr. of references to this node. Only ! relevant for first node in a list of ! siblings, in following siblings it is ! always one. */ ! char_u wn_byte; /* Byte for this node. NUL for word end */ ! ! /* Info for when "wn_byte" is NUL. ! * In PREFIXTREE "wn_region" is used for the prefcondnr. ! * In the soundfolded word tree "wn_flags" has the MSW of the wordnr and ! * "wn_region" the LSW of the wordnr. */ ! char_u wn_affixID; /* supported/required prefix ID or 0 */ ! short_u wn_flags; /* WF_ flags */ ! short wn_region; /* region mask */ #ifdef SPELL_PRINTTREE ! int wn_nr; /* sequence nr for printing */ #endif }; ! #define WN_MASK 0xffff /* mask relevant bits of "wn_flags" */ #define HI2WN(hi) (wordnode_T *)((hi)->hi_key) --- 1851,1890 ---- typedef struct wordnode_S wordnode_T; struct wordnode_S { ! union // shared to save space { ! char_u hashkey[6]; // the hash key, only used while compressing ! int index; // index in written nodes (valid after first ! // round) } wn_u1; ! union // shared to save space { ! wordnode_T *next; // next node with same hash key ! wordnode_T *wnode; // parent node that will write this node } wn_u2; ! wordnode_T *wn_child; // child (next byte in word) ! wordnode_T *wn_sibling; // next sibling (alternate byte in word, ! // always sorted) ! int wn_refs; // Nr. of references to this node. Only ! // relevant for first node in a list of ! // siblings, in following siblings it is ! // always one. ! char_u wn_byte; // Byte for this node. NUL for word end ! ! // Info for when "wn_byte" is NUL. ! // In PREFIXTREE "wn_region" is used for the prefcondnr. ! // In the soundfolded word tree "wn_flags" has the MSW of the wordnr and ! // "wn_region" the LSW of the wordnr. ! char_u wn_affixID; // supported/required prefix ID or 0 ! short_u wn_flags; // WF_ flags ! short wn_region; // region mask #ifdef SPELL_PRINTTREE ! int wn_nr; // sequence nr for printing #endif }; ! #define WN_MASK 0xffff // mask relevant bits of "wn_flags" #define HI2WN(hi) (wordnode_T *)((hi)->hi_key) *************** *** 1893,1965 **** */ typedef struct spellinfo_S { ! wordnode_T *si_foldroot; /* tree with case-folded words */ ! long si_foldwcount; /* nr of words in si_foldroot */ ! wordnode_T *si_keeproot; /* tree with keep-case words */ ! long si_keepwcount; /* nr of words in si_keeproot */ ! wordnode_T *si_prefroot; /* tree with postponed prefixes */ ! long si_sugtree; /* creating the soundfolding trie */ ! sblock_T *si_blocks; /* memory blocks used */ ! long si_blocks_cnt; /* memory blocks allocated */ ! int si_did_emsg; /* TRUE when ran out of memory */ ! long si_compress_cnt; /* words to add before lowering ! compression limit */ ! wordnode_T *si_first_free; /* List of nodes that have been freed during ! compression, linked by "wn_child" field. */ ! long si_free_count; /* number of nodes in si_first_free */ #ifdef SPELL_PRINTTREE ! int si_wordnode_nr; /* sequence nr for nodes */ #endif ! buf_T *si_spellbuf; /* buffer used to store soundfold word table */ ! int si_ascii; /* handling only ASCII words */ ! int si_add; /* addition file */ ! int si_clear_chartab; /* when TRUE clear char tables */ ! int si_region; /* region mask */ ! vimconv_T si_conv; /* for conversion to 'encoding' */ ! int si_memtot; /* runtime memory used */ ! int si_verbose; /* verbose messages */ ! int si_msg_count; /* number of words added since last message */ ! char_u *si_info; /* info text chars or NULL */ ! int si_region_count; /* number of regions supported (1 when there ! are no regions) */ char_u si_region_name[MAXREGIONS * 2 + 1]; ! /* region names; used only if ! * si_region_count > 1) */ ! garray_T si_rep; /* list of fromto_T entries from REP lines */ ! garray_T si_repsal; /* list of fromto_T entries from REPSAL lines */ ! garray_T si_sal; /* list of fromto_T entries from SAL lines */ ! char_u *si_sofofr; /* SOFOFROM text */ ! char_u *si_sofoto; /* SOFOTO text */ ! int si_nosugfile; /* NOSUGFILE item found */ ! int si_nosplitsugs; /* NOSPLITSUGS item found */ ! int si_nocompoundsugs; /* NOCOMPOUNDSUGS item found */ ! int si_followup; /* soundsalike: ? */ ! int si_collapse; /* soundsalike: ? */ ! hashtab_T si_commonwords; /* hashtable for common words */ ! time_t si_sugtime; /* timestamp for .sug file */ ! int si_rem_accents; /* soundsalike: remove accents */ ! garray_T si_map; /* MAP info concatenated */ ! char_u *si_midword; /* MIDWORD chars or NULL */ ! int si_compmax; /* max nr of words for compounding */ ! int si_compminlen; /* minimal length for compounding */ ! int si_compsylmax; /* max nr of syllables for compounding */ ! int si_compoptions; /* COMP_ flags */ ! garray_T si_comppat; /* CHECKCOMPOUNDPATTERN items, each stored as ! a string */ ! char_u *si_compflags; /* flags used for compounding */ ! char_u si_nobreak; /* NOBREAK */ ! char_u *si_syllable; /* syllable string */ ! garray_T si_prefcond; /* table with conditions for postponed ! * prefixes, each stored as a string */ ! int si_newprefID; /* current value for ah_newID */ ! int si_newcompID; /* current value for compound ID */ } spellinfo_T; static int is_aff_rule(char_u **items, int itemcnt, char *rulename, int mincount); --- 1893,1965 ---- */ typedef struct spellinfo_S { ! wordnode_T *si_foldroot; // tree with case-folded words ! long si_foldwcount; // nr of words in si_foldroot ! wordnode_T *si_keeproot; // tree with keep-case words ! long si_keepwcount; // nr of words in si_keeproot ! wordnode_T *si_prefroot; // tree with postponed prefixes ! long si_sugtree; // creating the soundfolding trie ! sblock_T *si_blocks; // memory blocks used ! long si_blocks_cnt; // memory blocks allocated ! int si_did_emsg; // TRUE when ran out of memory ! long si_compress_cnt; // words to add before lowering ! // compression limit ! wordnode_T *si_first_free; // List of nodes that have been freed during ! // compression, linked by "wn_child" field. ! long si_free_count; // number of nodes in si_first_free #ifdef SPELL_PRINTTREE ! int si_wordnode_nr; // sequence nr for nodes #endif ! buf_T *si_spellbuf; // buffer used to store soundfold word table ! int si_ascii; // handling only ASCII words ! int si_add; // addition file ! int si_clear_chartab; // when TRUE clear char tables ! int si_region; // region mask ! vimconv_T si_conv; // for conversion to 'encoding' ! int si_memtot; // runtime memory used ! int si_verbose; // verbose messages ! int si_msg_count; // number of words added since last message ! char_u *si_info; // info text chars or NULL ! int si_region_count; // number of regions supported (1 when there ! // are no regions) char_u si_region_name[MAXREGIONS * 2 + 1]; ! // region names; used only if ! // si_region_count > 1) ! garray_T si_rep; // list of fromto_T entries from REP lines ! garray_T si_repsal; // list of fromto_T entries from REPSAL lines ! garray_T si_sal; // list of fromto_T entries from SAL lines ! char_u *si_sofofr; // SOFOFROM text ! char_u *si_sofoto; // SOFOTO text ! int si_nosugfile; // NOSUGFILE item found ! int si_nosplitsugs; // NOSPLITSUGS item found ! int si_nocompoundsugs; // NOCOMPOUNDSUGS item found ! int si_followup; // soundsalike: ? ! int si_collapse; // soundsalike: ? ! hashtab_T si_commonwords; // hashtable for common words ! time_t si_sugtime; // timestamp for .sug file ! int si_rem_accents; // soundsalike: remove accents ! garray_T si_map; // MAP info concatenated ! char_u *si_midword; // MIDWORD chars or NULL ! int si_compmax; // max nr of words for compounding ! int si_compminlen; // minimal length for compounding ! int si_compsylmax; // max nr of syllables for compounding ! int si_compoptions; // COMP_ flags ! garray_T si_comppat; // CHECKCOMPOUNDPATTERN items, each stored as ! // a string ! char_u *si_compflags; // flags used for compounding ! char_u si_nobreak; // NOBREAK ! char_u *si_syllable; // syllable string ! garray_T si_prefcond; // table with conditions for postponed ! // prefixes, each stored as a string ! int si_newprefID; // current value for ah_newID ! int si_newcompID; // current value for compound ID } spellinfo_T; static int is_aff_rule(char_u **items, int itemcnt, char *rulename, int mincount); *************** *** 1997,2019 **** static void spell_message(spellinfo_T *spin, char_u *str); static void init_spellfile(void); ! /* In the postponed prefixes tree wn_flags is used to store the WFP_ flags, ! * but it must be negative to indicate the prefix tree to tree_add_word(). ! * Use a negative number with the lower 8 bits zero. */ #define PFX_FLAGS -256 ! /* flags for "condit" argument of store_aff_word() */ ! #define CONDIT_COMB 1 /* affix must combine */ ! #define CONDIT_CFIX 2 /* affix must have CIRCUMFIX flag */ ! #define CONDIT_SUF 4 /* add a suffix for matching flags */ ! #define CONDIT_AFF 8 /* word already has an affix */ /* * Tunable parameters for when the tree is compressed. See 'mkspellmem'. */ ! static long compress_start = 30000; /* memory / SBLOCKSIZE */ ! static long compress_inc = 100; /* memory / SBLOCKSIZE */ ! static long compress_added = 500000; /* word count */ /* * Check the 'mkspellmem' option. Return FAIL if it's wrong. --- 1997,2019 ---- static void spell_message(spellinfo_T *spin, char_u *str); static void init_spellfile(void); ! // In the postponed prefixes tree wn_flags is used to store the WFP_ flags, ! // but it must be negative to indicate the prefix tree to tree_add_word(). ! // Use a negative number with the lower 8 bits zero. #define PFX_FLAGS -256 ! // flags for "condit" argument of store_aff_word() ! #define CONDIT_COMB 1 // affix must combine ! #define CONDIT_CFIX 2 // affix must have CIRCUMFIX flag ! #define CONDIT_SUF 4 // add a suffix for matching flags ! #define CONDIT_AFF 8 // word already has an affix /* * Tunable parameters for when the tree is compressed. See 'mkspellmem'. */ ! static long compress_start = 30000; // memory / SBLOCKSIZE ! static long compress_inc = 100; // memory / SBLOCKSIZE ! static long compress_added = 500000; // word count /* * Check the 'mkspellmem' option. Return FAIL if it's wrong. *************** *** 2029,2035 **** if (!VIM_ISDIGIT(*p)) return FAIL; ! /* block count = (value * 1024) / SBLOCKSIZE (but avoid overflow)*/ start = (getdigits(&p) * 10) / (SBLOCKSIZE / 102); if (*p != ',') return FAIL; --- 2029,2035 ---- if (!VIM_ISDIGIT(*p)) return FAIL; ! // block count = (value * 1024) / SBLOCKSIZE (but avoid overflow) start = (getdigits(&p) * 10) / (SBLOCKSIZE / 102); if (*p != ',') return FAIL; *************** *** 2089,2095 **** { if (node->wn_u1.index) { ! /* Done this node before, print the reference. */ PRINTSOME(line1, depth, "(%d)", node->wn_nr, 0); PRINTSOME(line2, depth, " ", 0, 0); PRINTSOME(line3, depth, " ", 0, 0); --- 2089,2095 ---- { if (node->wn_u1.index) { ! // Done this node before, print the reference. PRINTSOME(line1, depth, "(%d)", node->wn_nr, 0); PRINTSOME(line2, depth, " ", 0, 0); PRINTSOME(line3, depth, " ", 0, 0); *************** *** 2106,2112 **** if (node->wn_child != NULL) PRINTSOME(line1, depth, " %c -> ", node->wn_byte, 0); else ! /* Cannot happen? */ PRINTSOME(line1, depth, " %c ???", node->wn_byte, 0); } else --- 2106,2112 ---- if (node->wn_child != NULL) PRINTSOME(line1, depth, " %c -> ", node->wn_byte, 0); else ! // Cannot happen? PRINTSOME(line1, depth, " %c ???", node->wn_byte, 0); } else *************** *** 2126,2139 **** msg(line3); } ! /* do the children */ if (node->wn_byte != NUL && node->wn_child != NULL) spell_print_node(node->wn_child, depth + 1); ! /* do the siblings */ if (node->wn_sibling != NULL) { ! /* get rid of all parent details except | */ STRCPY(line1, line3); STRCPY(line2, line3); spell_print_node(node->wn_sibling, depth); --- 2126,2139 ---- msg(line3); } ! // do the children if (node->wn_byte != NUL && node->wn_child != NULL) spell_print_node(node->wn_child, depth + 1); ! // do the siblings if (node->wn_sibling != NULL) { ! // get rid of all parent details except | STRCPY(line1, line3); STRCPY(line2, line3); spell_print_node(node->wn_sibling, depth); *************** *** 2146,2160 **** { if (root != NULL) { ! /* Clear the "wn_u1.index" fields, used to remember what has been ! * done. */ spell_clear_flags(root); ! /* Recursively print the tree. */ spell_print_node(root, 0); } } ! #endif /* SPELL_PRINTTREE */ /* * Read the affix file "fname". --- 2146,2160 ---- { if (root != NULL) { ! // Clear the "wn_u1.index" fields, used to remember what has been ! // done. spell_clear_flags(root); ! // Recursively print the tree. spell_print_node(root, 0); } } ! #endif // SPELL_PRINTTREE /* * Read the affix file "fname". *************** *** 2187,2202 **** int found_map = FALSE; hashitem_T *hi; int l; ! int compminlen = 0; /* COMPOUNDMIN value */ ! int compsylmax = 0; /* COMPOUNDSYLMAX value */ ! int compoptions = 0; /* COMP_ flags */ ! int compmax = 0; /* COMPOUNDWORDMAX value */ ! char_u *compflags = NULL; /* COMPOUNDFLAG and COMPOUNDRULE ! concatenated */ ! char_u *midword = NULL; /* MIDWORD value */ ! char_u *syllable = NULL; /* SYLLABLE value */ ! char_u *sofofrom = NULL; /* SOFOFROM value */ ! char_u *sofoto = NULL; /* SOFOTO value */ /* * Open the file. --- 2187,2202 ---- int found_map = FALSE; hashitem_T *hi; int l; ! int compminlen = 0; // COMPOUNDMIN value ! int compsylmax = 0; // COMPOUNDSYLMAX value ! int compoptions = 0; // COMP_ flags ! int compmax = 0; // COMPOUNDWORDMAX value ! char_u *compflags = NULL; // COMPOUNDFLAG and COMPOUNDRULE ! // concatenated ! char_u *midword = NULL; // MIDWORD value ! char_u *syllable = NULL; // SYLLABLE value ! char_u *sofofrom = NULL; // SOFOFROM value ! char_u *sofoto = NULL; // SOFOTO value /* * Open the file. *************** *** 2211,2226 **** vim_snprintf((char *)IObuff, IOSIZE, _("Reading affix file %s..."), fname); spell_message(spin, IObuff); ! /* Only do REP lines when not done in another .aff file already. */ do_rep = spin->si_rep.ga_len == 0; ! /* Only do REPSAL lines when not done in another .aff file already. */ do_repsal = spin->si_repsal.ga_len == 0; ! /* Only do SAL lines when not done in another .aff file already. */ do_sal = spin->si_sal.ga_len == 0; ! /* Only do MAP lines when not done in another .aff file already. */ do_mapline = spin->si_map.ga_len == 0; /* --- 2211,2226 ---- vim_snprintf((char *)IObuff, IOSIZE, _("Reading affix file %s..."), fname); spell_message(spin, IObuff); ! // Only do REP lines when not done in another .aff file already. do_rep = spin->si_rep.ga_len == 0; ! // Only do REPSAL lines when not done in another .aff file already. do_repsal = spin->si_repsal.ga_len == 0; ! // Only do SAL lines when not done in another .aff file already. do_sal = spin->si_sal.ga_len == 0; ! // Only do MAP lines when not done in another .aff file already. do_mapline = spin->si_map.ga_len == 0; /* *************** *** 2244,2254 **** line_breakcheck(); ++lnum; ! /* Skip comment lines. */ if (*rline == '#') continue; ! /* Convert from "SET" to 'encoding' when needed. */ vim_free(pc); if (spin->si_conv.vc_type != CONV_NONE) { --- 2244,2254 ---- line_breakcheck(); ++lnum; ! // Skip comment lines. if (*rline == '#') continue; ! // Convert from "SET" to 'encoding' when needed. vim_free(pc); if (spin->si_conv.vc_type != CONV_NONE) { *************** *** 2267,2302 **** line = rline; } ! /* Split the line up in white separated items. Put a NUL after each ! * item. */ itemcnt = 0; for (p = line; ; ) { ! while (*p != NUL && *p <= ' ') /* skip white space and CR/NL */ ++p; if (*p == NUL) break; ! if (itemcnt == MAXITEMCNT) /* too many items */ break; items[itemcnt++] = p; ! /* A few items have arbitrary text argument, don't split them. */ if (itemcnt == 2 && spell_info_item(items[0])) ! while (*p >= ' ' || *p == TAB) /* skip until CR/NL */ ++p; else ! while (*p > ' ') /* skip until white space or CR/NL */ ++p; if (*p == NUL) break; *p++ = NUL; } ! /* Handle non-empty lines. */ if (itemcnt > 0) { if (is_aff_rule(items, itemcnt, "SET", 2) && aff->af_enc == NULL) { ! /* Setup for conversion from "ENC" to 'encoding'. */ aff->af_enc = enc_canonize(items[1]); if (aff->af_enc != NULL && !spin->si_ascii && convert_setup(&spin->si_conv, aff->af_enc, --- 2267,2302 ---- line = rline; } ! // Split the line up in white separated items. Put a NUL after each ! // item. itemcnt = 0; for (p = line; ; ) { ! while (*p != NUL && *p <= ' ') // skip white space and CR/NL ++p; if (*p == NUL) break; ! if (itemcnt == MAXITEMCNT) // too many items break; items[itemcnt++] = p; ! // A few items have arbitrary text argument, don't split them. if (itemcnt == 2 && spell_info_item(items[0])) ! while (*p >= ' ' || *p == TAB) // skip until CR/NL ++p; else ! while (*p > ' ') // skip until white space or CR/NL ++p; if (*p == NUL) break; *p++ = NUL; } ! // Handle non-empty lines. if (itemcnt > 0) { if (is_aff_rule(items, itemcnt, "SET", 2) && aff->af_enc == NULL) { ! // Setup for conversion from "ENC" to 'encoding'. aff->af_enc = enc_canonize(items[1]); if (aff->af_enc != NULL && !spin->si_ascii && convert_setup(&spin->si_conv, aff->af_enc, *************** *** 2357,2365 **** } else if (is_aff_rule(items, itemcnt, "TRY", 2)) { ! /* ignored, we look in the tree for what chars may appear */ } ! /* TODO: remove "RAR" later */ else if ((is_aff_rule(items, itemcnt, "RAR", 2) || is_aff_rule(items, itemcnt, "RARE", 2)) && aff->af_rare == 0) --- 2357,2365 ---- } else if (is_aff_rule(items, itemcnt, "TRY", 2)) { ! // ignored, we look in the tree for what chars may appear } ! // TODO: remove "RAR" later else if ((is_aff_rule(items, itemcnt, "RAR", 2) || is_aff_rule(items, itemcnt, "RARE", 2)) && aff->af_rare == 0) *************** *** 2367,2373 **** aff->af_rare = affitem2flag(aff->af_flagtype, items[1], fname, lnum); } ! /* TODO: remove "KEP" later */ else if ((is_aff_rule(items, itemcnt, "KEP", 2) || is_aff_rule(items, itemcnt, "KEEPCASE", 2)) && aff->af_keepcase == 0) --- 2367,2373 ---- aff->af_rare = affitem2flag(aff->af_flagtype, items[1], fname, lnum); } ! // TODO: remove "KEP" later else if ((is_aff_rule(items, itemcnt, "KEP", 2) || is_aff_rule(items, itemcnt, "KEEPCASE", 2)) && aff->af_keepcase == 0) *************** *** 2434,2441 **** else if (is_aff_rule(items, itemcnt, "COMPOUNDFLAG", 2) && compflags == NULL) { ! /* Turn flag "c" into COMPOUNDRULE compatible string "c+", ! * "Na" into "Na+", "1234" into "1234+". */ p = getroom(spin, STRLEN(items[1]) + 2, FALSE); if (p != NULL) { --- 2434,2441 ---- else if (is_aff_rule(items, itemcnt, "COMPOUNDFLAG", 2) && compflags == NULL) { ! // Turn flag "c" into COMPOUNDRULE compatible string "c+", ! // "Na" into "Na+", "1234" into "1234+". p = getroom(spin, STRLEN(items[1]) + 2, FALSE); if (p != NULL) { *************** *** 2446,2464 **** } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2)) { ! /* We don't use the count, but do check that it's a number and ! * not COMPOUNDRULE mistyped. */ if (atoi((char *)items[1]) == 0) smsg(_("Wrong COMPOUNDRULES value in %s line %d: %s"), fname, lnum, items[1]); } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2)) { ! /* Don't use the first rule if it is a number. */ if (compflags != NULL || *skipdigits(items[1]) != NUL) { ! /* Concatenate this string to previously defined ones, ! * using a slash to separate them. */ l = (int)STRLEN(items[1]) + 1; if (compflags != NULL) l += (int)STRLEN(compflags) + 1; --- 2446,2464 ---- } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2)) { ! // We don't use the count, but do check that it's a number and ! // not COMPOUNDRULE mistyped. if (atoi((char *)items[1]) == 0) smsg(_("Wrong COMPOUNDRULES value in %s line %d: %s"), fname, lnum, items[1]); } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2)) { ! // Don't use the first rule if it is a number. if (compflags != NULL || *skipdigits(items[1]) != NUL) { ! // Concatenate this string to previously defined ones, ! // using a slash to separate them. l = (int)STRLEN(items[1]) + 1; if (compflags != NULL) l += (int)STRLEN(compflags) + 1; *************** *** 2526,2532 **** garray_T *gap = &spin->si_comppat; int i; ! /* Only add the couple if it isn't already there. */ for (i = 0; i < gap->ga_len - 1; i += 2) if (STRCMP(((char_u **)(gap->ga_data))[i], items[1]) == 0 && STRCMP(((char_u **)(gap->ga_data))[i + 1], --- 2526,2532 ---- garray_T *gap = &spin->si_comppat; int i; ! // Only add the couple if it isn't already there. for (i = 0; i < gap->ga_len - 1; i += 2) if (STRCMP(((char_u **)(gap->ga_data))[i], items[1]) == 0 && STRCMP(((char_u **)(gap->ga_data))[i + 1], *************** *** 2582,2591 **** else tp = &aff->af_suff; ! /* Myspell allows the same affix name to be used multiple ! * times. The affix files that do this have an undocumented ! * "S" flag on all but the last block, thus we check for that ! * and store it in ah_follows. */ vim_strncpy(key, items[1], AH_KEY_LEN - 1); hi = hash_find(tp, key); if (!HASHITEM_EMPTY(hi)) --- 2582,2591 ---- else tp = &aff->af_suff; ! // Myspell allows the same affix name to be used multiple ! // times. The affix files that do this have an undocumented ! // "S" flag on all but the last block, thus we check for that ! // and store it in ah_follows. vim_strncpy(key, items[1], AH_KEY_LEN - 1); hi = hash_find(tp, key); if (!HASHITEM_EMPTY(hi)) *************** *** 2600,2606 **** } else { ! /* New affix letter. */ cur_aff = (affheader_T *)getroom(spin, sizeof(affheader_T), TRUE); if (cur_aff == NULL) --- 2600,2606 ---- } else { ! // New affix letter. cur_aff = (affheader_T *)getroom(spin, sizeof(affheader_T), TRUE); if (cur_aff == NULL) *************** *** 2625,2632 **** cur_aff->ah_combine = (*items[2] == 'Y'); } ! /* Check for the "S" flag, which apparently means that another ! * block with the same affix name is following. */ if (itemcnt > lasti && STRCMP(items[lasti], "S") == 0) { ++lasti; --- 2625,2632 ---- cur_aff->ah_combine = (*items[2] == 'Y'); } ! // Check for the "S" flag, which apparently means that another ! // block with the same affix name is following. if (itemcnt > lasti && STRCMP(items[lasti], "S") == 0) { ++lasti; *************** *** 2635,2642 **** else cur_aff->ah_follows = FALSE; ! /* Myspell allows extra text after the item, but that might ! * mean mistakes go unnoticed. Require a comment-starter. */ if (itemcnt > lasti && *items[lasti] != '#') smsg(_(e_afftrailing), fname, lnum, items[lasti]); --- 2635,2642 ---- else cur_aff->ah_follows = FALSE; ! // Myspell allows extra text after the item, but that might ! // mean mistakes go unnoticed. Require a comment-starter. if (itemcnt > lasti && *items[lasti] != '#') smsg(_(e_afftrailing), fname, lnum, items[lasti]); *************** *** 2648,2665 **** { if (cur_aff->ah_newID == 0) { ! /* Use a new number in the .spl file later, to be able ! * to handle multiple .aff files. */ check_renumber(spin); cur_aff->ah_newID = ++spin->si_newprefID; ! /* We only really use ah_newID if the prefix is ! * postponed. We know that only after handling all ! * the items. */ did_postpone_prefix = FALSE; } else ! /* Did use the ID in a previous block. */ did_postpone_prefix = TRUE; } --- 2648,2665 ---- { if (cur_aff->ah_newID == 0) { ! // Use a new number in the .spl file later, to be able ! // to handle multiple .aff files. check_renumber(spin); cur_aff->ah_newID = ++spin->si_newprefID; ! // We only really use ah_newID if the prefix is ! // postponed. We know that only after handling all ! // the items. did_postpone_prefix = FALSE; } else ! // Did use the ID in a previous block. did_postpone_prefix = TRUE; } *************** *** 2675,2683 **** int upper = FALSE; int lasti = 5; ! /* Myspell allows extra text after the item, but that might ! * mean mistakes go unnoticed. Require a comment-starter, ! * unless IGNOREEXTRA is used. Hunspell uses a "-" item. */ if (itemcnt > lasti && !aff->af_ignoreextra && *items[lasti] != '#' --- 2675,2683 ---- int upper = FALSE; int lasti = 5; ! // Myspell allows extra text after the item, but that might ! // mean mistakes go unnoticed. Require a comment-starter, ! // unless IGNOREEXTRA is used. Hunspell uses a "-" item. if (itemcnt > lasti && !aff->af_ignoreextra && *items[lasti] != '#' *************** *** 2685,2691 **** || itemcnt != lasti + 1)) smsg(_(e_afftrailing), fname, lnum, items[lasti]); ! /* New item for an affix letter. */ --aff_todo; aff_entry = (affentry_T *)getroom(spin, sizeof(affentry_T), TRUE); --- 2685,2691 ---- || itemcnt != lasti + 1)) smsg(_(e_afftrailing), fname, lnum, items[lasti]); ! // New item for an affix letter. --aff_todo; aff_entry = (affentry_T *)getroom(spin, sizeof(affentry_T), TRUE); *************** *** 2698,2704 **** { aff_entry->ae_add = getroom_save(spin, items[3]); ! /* Recognize flags on the affix: abcd/XYZ */ aff_entry->ae_flags = vim_strchr(aff_entry->ae_add, '/'); if (aff_entry->ae_flags != NULL) { --- 2698,2704 ---- { aff_entry->ae_add = getroom_save(spin, items[3]); ! // Recognize flags on the affix: abcd/XYZ aff_entry->ae_flags = vim_strchr(aff_entry->ae_add, '/'); if (aff_entry->ae_flags != NULL) { *************** *** 2707,2714 **** } } ! /* Don't use an affix entry with non-ASCII characters when ! * "spin->si_ascii" is TRUE. */ if (!spin->si_ascii || !(has_non_ascii(aff_entry->ae_chop) || has_non_ascii(aff_entry->ae_add))) { --- 2707,2714 ---- } } ! // Don't use an affix entry with non-ASCII characters when ! // "spin->si_ascii" is TRUE. if (!spin->si_ascii || !(has_non_ascii(aff_entry->ae_chop) || has_non_ascii(aff_entry->ae_add))) { *************** *** 2731,2748 **** fname, lnum, items[4]); } ! /* For postponed prefixes we need an entry in si_prefcond ! * for the condition. Use an existing one if possible. ! * Can't be done for an affix with flags, ignoring ! * COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG. */ if (*items[0] == 'P' && aff->af_pfxpostpone && aff_entry->ae_flags == NULL) { ! /* When the chop string is one lower-case letter and ! * the add string ends in the upper-case letter we set ! * the "upper" flag, clear "ae_chop" and remove the ! * letters from "ae_add". The condition must either ! * be empty or start with the same letter. */ if (aff_entry->ae_chop != NULL && aff_entry->ae_add != NULL && aff_entry->ae_chop[(*mb_ptr2len)( --- 2731,2748 ---- fname, lnum, items[4]); } ! // For postponed prefixes we need an entry in si_prefcond ! // for the condition. Use an existing one if possible. ! // Can't be done for an affix with flags, ignoring ! // COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG. if (*items[0] == 'P' && aff->af_pfxpostpone && aff_entry->ae_flags == NULL) { ! // When the chop string is one lower-case letter and ! // the add string ends in the upper-case letter we set ! // the "upper" flag, clear "ae_chop" and remove the ! // letters from "ae_add". The condition must either ! // be empty or start with the same letter. if (aff_entry->ae_chop != NULL && aff_entry->ae_add != NULL && aff_entry->ae_chop[(*mb_ptr2len)( *************** *** 2765,2773 **** aff_entry->ae_chop = NULL; *p = NUL; ! /* The condition is matched with the ! * actual word, thus must check for the ! * upper-case letter. */ if (aff_entry->ae_cond != NULL) { char_u buf[MAXLINELEN]; --- 2765,2773 ---- aff_entry->ae_chop = NULL; *p = NUL; ! // The condition is matched with the ! // actual word, thus must check for the ! // upper-case letter. if (aff_entry->ae_cond != NULL) { char_u buf[MAXLINELEN]; *************** *** 2800,2806 **** char_u **pp; int n; ! /* Find a previously used condition. */ for (idx = spin->si_prefcond.ga_len - 1; idx >= 0; --idx) { --- 2800,2806 ---- char_u **pp; int n; ! // Find a previously used condition. for (idx = spin->si_prefcond.ga_len - 1; idx >= 0; --idx) { *************** *** 2810,2816 **** } if (idx < 0 && ga_grow(&spin->si_prefcond, 1) == OK) { ! /* Not found, add a new condition. */ idx = spin->si_prefcond.ga_len++; pp = ((char_u **)spin->si_prefcond.ga_data) + idx; --- 2810,2816 ---- } if (idx < 0 && ga_grow(&spin->si_prefcond, 1) == OK) { ! // Not found, add a new condition. idx = spin->si_prefcond.ga_len++; pp = ((char_u **)spin->si_prefcond.ga_data) + idx; *************** *** 2821,2834 **** aff_entry->ae_cond); } ! /* Add the prefix to the prefix tree. */ if (aff_entry->ae_add == NULL) p = (char_u *)""; else p = aff_entry->ae_add; ! /* PFX_FLAGS is a negative number, so that ! * tree_add_word() knows this is the prefix tree. */ n = PFX_FLAGS; if (!cur_aff->ah_combine) n |= WFP_NC; --- 2821,2834 ---- aff_entry->ae_cond); } ! // Add the prefix to the prefix tree. if (aff_entry->ae_add == NULL) p = (char_u *)""; else p = aff_entry->ae_add; ! // PFX_FLAGS is a negative number, so that ! // tree_add_word() knows this is the prefix tree. n = PFX_FLAGS; if (!cur_aff->ah_combine) n |= WFP_NC; *************** *** 2843,2849 **** did_postpone_prefix = TRUE; } ! /* Didn't actually use ah_newID, backup si_newprefID. */ if (aff_todo == 0 && !did_postpone_prefix) { --spin->si_newprefID; --- 2843,2849 ---- did_postpone_prefix = TRUE; } ! // Didn't actually use ah_newID, backup si_newprefID. if (aff_todo == 0 && !did_postpone_prefix) { --spin->si_newprefID; *************** *** 2867,2873 **** else if (is_aff_rule(items, itemcnt, "REP", 2) || is_aff_rule(items, itemcnt, "REPSAL", 2)) { ! /* Ignore REP/REPSAL count */; if (!isdigit(*items[1])) smsg(_("Expected REP(SAL) count in %s line %d"), fname, lnum); --- 2867,2873 ---- else if (is_aff_rule(items, itemcnt, "REP", 2) || is_aff_rule(items, itemcnt, "REPSAL", 2)) { ! // Ignore REP/REPSAL count if (!isdigit(*items[1])) smsg(_("Expected REP(SAL) count in %s line %d"), fname, lnum); *************** *** 2876,2890 **** || STRCMP(items[0], "REPSAL") == 0) && itemcnt >= 3) { ! /* REP/REPSAL item */ ! /* Myspell ignores extra arguments, we require it starts with ! * # to detect mistakes. */ if (itemcnt > 3 && items[3][0] != '#') smsg(_(e_afftrailing), fname, lnum, items[3]); if (items[0][3] == 'S' ? do_repsal : do_rep) { ! /* Replace underscore with space (can't include a space ! * directly). */ for (p = items[1]; *p != NUL; MB_PTR_ADV(p)) if (*p == '_') *p = ' '; --- 2876,2890 ---- || STRCMP(items[0], "REPSAL") == 0) && itemcnt >= 3) { ! // REP/REPSAL item ! // Myspell ignores extra arguments, we require it starts with ! // # to detect mistakes. if (itemcnt > 3 && items[3][0] != '#') smsg(_(e_afftrailing), fname, lnum, items[3]); if (items[0][3] == 'S' ? do_repsal : do_rep) { ! // Replace underscore with space (can't include a space ! // directly). for (p = items[1]; *p != NUL; MB_PTR_ADV(p)) if (*p == '_') *p = ' '; *************** *** 2898,2907 **** } else if (is_aff_rule(items, itemcnt, "MAP", 2)) { ! /* MAP item or count */ if (!found_map) { ! /* First line contains the count. */ found_map = TRUE; if (!isdigit(*items[1])) smsg(_("Expected MAP count in %s line %d"), --- 2898,2907 ---- } else if (is_aff_rule(items, itemcnt, "MAP", 2)) { ! // MAP item or count if (!found_map) { ! // First line contains the count. found_map = TRUE; if (!isdigit(*items[1])) smsg(_("Expected MAP count in %s line %d"), *************** *** 2911,2917 **** { int c; ! /* Check that every character appears only once. */ for (p = items[1]; *p != NUL; ) { c = mb_ptr2char_adv(&p); --- 2911,2917 ---- { int c; ! // Check that every character appears only once. for (p = items[1]; *p != NUL; ) { c = mb_ptr2char_adv(&p); *************** *** 2923,2941 **** fname, lnum); } ! /* We simply concatenate all the MAP strings, separated by ! * slashes. */ ga_concat(&spin->si_map, items[1]); ga_append(&spin->si_map, '/'); } } ! /* Accept "SAL from to" and "SAL from to #comment". */ else if (is_aff_rule(items, itemcnt, "SAL", 3)) { if (do_sal) { ! /* SAL item (sounds-a-like) ! * Either one of the known keys or a from-to pair. */ if (STRCMP(items[1], "followup") == 0) spin->si_followup = sal_to_bool(items[2]); else if (STRCMP(items[1], "collapse_result") == 0) --- 2923,2941 ---- fname, lnum); } ! // We simply concatenate all the MAP strings, separated by ! // slashes. ga_concat(&spin->si_map, items[1]); ga_append(&spin->si_map, '/'); } } ! // Accept "SAL from to" and "SAL from to #comment". else if (is_aff_rule(items, itemcnt, "SAL", 3)) { if (do_sal) { ! // SAL item (sounds-a-like) ! // Either one of the known keys or a from-to pair. if (STRCMP(items[1], "followup") == 0) spin->si_followup = sal_to_bool(items[2]); else if (STRCMP(items[1], "collapse_result") == 0) *************** *** 2943,2949 **** else if (STRCMP(items[1], "remove_accents") == 0) spin->si_rem_accents = sal_to_bool(items[2]); else ! /* when "to" is "_" it means empty */ add_fromto(spin, &spin->si_sal, items[1], STRCMP(items[2], "_") == 0 ? (char_u *)"" : items[2]); --- 2943,2949 ---- else if (STRCMP(items[1], "remove_accents") == 0) spin->si_rem_accents = sal_to_bool(items[2]); else ! // when "to" is "_" it means empty add_fromto(spin, &spin->si_sal, items[1], STRCMP(items[2], "_") == 0 ? (char_u *)"" : items[2]); *************** *** 2985,2992 **** { if (spin->si_clear_chartab) { ! /* Clear the char type tables, don't want to use any of the ! * currently used spell properties. */ init_spell_chartab(); spin->si_clear_chartab = FALSE; } --- 2985,2992 ---- { if (spin->si_clear_chartab) { ! // Clear the char type tables, don't want to use any of the ! // currently used spell properties. init_spell_chartab(); spin->si_clear_chartab = FALSE; } *************** *** 3010,3016 **** vim_free(upp); } ! /* Use compound specifications of the .aff file for the spell info. */ if (compmax != 0) { aff_check_number(spin->si_compmax, compmax, "COMPOUNDWORDMAX"); --- 3010,3016 ---- vim_free(upp); } ! // Use compound specifications of the .aff file for the spell info. if (compmax != 0) { aff_check_number(spin->si_compmax, compmax, "COMPOUNDWORDMAX"); *************** *** 3040,3046 **** if (compflags != NULL) process_compflags(spin, aff, compflags); ! /* Check that we didn't use too many renumbered flags. */ if (spin->si_newcompID < spin->si_newprefID) { if (spin->si_newcompID == 127 || spin->si_newcompID == 255) --- 3040,3046 ---- if (compflags != NULL) process_compflags(spin, aff, compflags); ! // Check that we didn't use too many renumbered flags. if (spin->si_newcompID < spin->si_newprefID) { if (spin->si_newcompID == 127 || spin->si_newcompID == 255) *************** *** 3131,3137 **** ++p; } if (*entry->ae_flags == NUL) ! entry->ae_flags = NULL; /* nothing left */ } } --- 3131,3137 ---- ++p; } if (*entry->ae_flags == NUL) ! entry->ae_flags = NULL; // nothing left } } *************** *** 3196,3202 **** { if (!VIM_ISDIGIT(**pp)) { ! ++*pp; /* always advance, avoid getting stuck */ return 0; } res = getdigits(pp); --- 3196,3202 ---- { if (!VIM_ISDIGIT(**pp)) { ! ++*pp; // always advance, avoid getting stuck return 0; } res = getdigits(pp); *************** *** 3239,3247 **** char_u key[AH_KEY_LEN]; hashitem_T *hi; ! /* Make room for the old and the new compflags, concatenated with a / in ! * between. Processing it makes it shorter, but we don't know by how ! * much, thus allocate the maximum. */ len = (int)STRLEN(compflags) + 1; if (spin->si_compflags != NULL) len += (int)STRLEN(spin->si_compflags) + 1; --- 3239,3247 ---- char_u key[AH_KEY_LEN]; hashitem_T *hi; ! // Make room for the old and the new compflags, concatenated with a / in ! // between. Processing it makes it shorter, but we don't know by how ! // much, thus allocate the maximum. len = (int)STRLEN(compflags) + 1; if (spin->si_compflags != NULL) len += (int)STRLEN(spin->si_compflags) + 1; *************** *** 3259,3275 **** for (p = compflags; *p != NUL; ) { if (vim_strchr((char_u *)"/?*+[]", *p) != NULL) ! /* Copy non-flag characters directly. */ *tp++ = *p++; else { ! /* First get the flag number, also checks validity. */ prevp = p; flag = get_affitem(aff->af_flagtype, &p); if (flag != 0) { ! /* Find the flag in the hashtable. If it was used before, use ! * the existing ID. Otherwise add a new entry. */ vim_strncpy(key, prevp, p - prevp); hi = hash_find(&aff->af_comp, key); if (!HASHITEM_EMPTY(hi)) --- 3259,3275 ---- for (p = compflags; *p != NUL; ) { if (vim_strchr((char_u *)"/?*+[]", *p) != NULL) ! // Copy non-flag characters directly. *tp++ = *p++; else { ! // First get the flag number, also checks validity. prevp = p; flag = get_affitem(aff->af_flagtype, &p); if (flag != 0) { ! // Find the flag in the hashtable. If it was used before, use ! // the existing ID. Otherwise add a new entry. vim_strncpy(key, prevp, p - prevp); hi = hash_find(&aff->af_comp, key); if (!HASHITEM_EMPTY(hi)) *************** *** 3281,3288 **** break; STRCPY(ci->ci_key, key); ci->ci_flag = flag; ! /* Avoid using a flag ID that has a special meaning in a ! * regexp (also inside []). */ do { check_renumber(spin); --- 3281,3288 ---- break; STRCPY(ci->ci_key, key); ci->ci_flag = flag; ! // Avoid using a flag ID that has a special meaning in a ! // regexp (also inside []). do { check_renumber(spin); *************** *** 3352,3358 **** n = ZERO_FLAG; if (n == flag) return TRUE; ! if (*p != NUL) /* skip over comma */ ++p; } break; --- 3352,3358 ---- n = ZERO_FLAG; if (n == flag) return TRUE; ! if (*p != NUL) // skip over comma ++p; } break; *************** *** 3440,3446 **** vim_free(aff->af_enc); ! /* All this trouble to free the "ae_prog" items... */ for (ht = &aff->af_pref; ; ht = &aff->af_suff) { todo = (int)ht->ht_used; --- 3440,3446 ---- vim_free(aff->af_enc); ! // All this trouble to free the "ae_prog" items... for (ht = &aff->af_pref; ; ht = &aff->af_suff) { todo = (int)ht->ht_used; *************** *** 3501,3517 **** return FAIL; } ! /* The hashtable is only used to detect duplicated words. */ hash_init(&ht); vim_snprintf((char *)IObuff, IOSIZE, _("Reading dictionary file %s..."), fname); spell_message(spin, IObuff); ! /* start with a message for the first line */ spin->si_msg_count = 999999; ! /* Read and ignore the first line: word count. */ (void)vim_fgets(line, MAXLINELEN, fd); if (!vim_isdigit(*skipwhite(line))) semsg(_("E760: No word count in %s"), fname); --- 3501,3517 ---- return FAIL; } ! // The hashtable is only used to detect duplicated words. hash_init(&ht); vim_snprintf((char *)IObuff, IOSIZE, _("Reading dictionary file %s..."), fname); spell_message(spin, IObuff); ! // start with a message for the first line spin->si_msg_count = 999999; ! // Read and ignore the first line: word count. (void)vim_fgets(line, MAXLINELEN, fd); if (!vim_isdigit(*skipwhite(line))) semsg(_("E760: No word count in %s"), fname); *************** *** 3526,3543 **** line_breakcheck(); ++lnum; if (line[0] == '#' || line[0] == '/') ! continue; /* comment line */ ! /* Remove CR, LF and white space from the end. White space halfway ! * the word is kept to allow e.g., "et al.". */ l = (int)STRLEN(line); while (l > 0 && line[l - 1] <= ' ') --l; if (l == 0) ! continue; /* empty line */ line[l] = NUL; ! /* Convert from "SET" to 'encoding' when needed. */ if (spin->si_conv.vc_type != CONV_NONE) { pc = string_convert(&spin->si_conv, line, NULL); --- 3526,3543 ---- line_breakcheck(); ++lnum; if (line[0] == '#' || line[0] == '/') ! continue; // comment line ! // Remove CR, LF and white space from the end. White space halfway ! // the word is kept to allow e.g., "et al.". l = (int)STRLEN(line); while (l > 0 && line[l - 1] <= ' ') --l; if (l == 0) ! continue; // empty line line[l] = NUL; ! // Convert from "SET" to 'encoding' when needed. if (spin->si_conv.vc_type != CONV_NONE) { pc = string_convert(&spin->si_conv, line, NULL); *************** *** 3555,3562 **** w = line; } ! /* Truncate the word at the "/", set "afflist" to what follows. ! * Replace "\/" by "/" and "\\" by "\". */ afflist = NULL; for (p = w; *p != NUL; MB_PTR_ADV(p)) { --- 3555,3562 ---- w = line; } ! // Truncate the word at the "/", set "afflist" to what follows. ! // Replace "\/" by "/" and "\\" by "\". afflist = NULL; for (p = w; *p != NUL; MB_PTR_ADV(p)) { *************** *** 3570,3576 **** } } ! /* Skip non-ASCII words when "spin->si_ascii" is TRUE. */ if (spin->si_ascii && has_non_ascii(w)) { ++non_ascii; --- 3570,3576 ---- } } ! // Skip non-ASCII words when "spin->si_ascii" is TRUE. if (spin->si_ascii && has_non_ascii(w)) { ++non_ascii; *************** *** 3578,3584 **** continue; } ! /* This takes time, print a message every 10000 words. */ if (spin->si_verbose && spin->si_msg_count > 10000) { spin->si_msg_count = 0; --- 3578,3584 ---- continue; } ! // This takes time, print a message every 10000 words. if (spin->si_verbose && spin->si_msg_count > 10000) { spin->si_msg_count = 0; *************** *** 3593,3599 **** out_flush(); } ! /* Store the word in the hashtable to be able to find duplicates. */ dw = (char_u *)getroom_save(spin, w); if (dw == NULL) { --- 3593,3599 ---- out_flush(); } ! // Store the word in the hashtable to be able to find duplicates. dw = (char_u *)getroom_save(spin, w); if (dw == NULL) { *************** *** 3623,3629 **** need_affix = FALSE; if (afflist != NULL) { ! /* Extract flags from the affix list. */ flags |= get_affix_flags(affile, afflist); if (affile->af_needaffix != 0 && flag_in_afflist( --- 3623,3629 ---- need_affix = FALSE; if (afflist != NULL) { ! // Extract flags from the affix list. flags |= get_affix_flags(affile, afflist); if (affile->af_needaffix != 0 && flag_in_afflist( *************** *** 3631,3660 **** need_affix = TRUE; if (affile->af_pfxpostpone) ! /* Need to store the list of prefix IDs with the word. */ pfxlen = get_pfxlist(affile, afflist, store_afflist); if (spin->si_compflags != NULL) ! /* Need to store the list of compound flags with the word. ! * Concatenate them to the list of prefix IDs. */ get_compflags(affile, afflist, store_afflist + pfxlen); } ! /* Add the word to the word tree(s). */ if (store_word(spin, dw, flags, spin->si_region, store_afflist, need_affix) == FAIL) retval = FAIL; if (afflist != NULL) { ! /* Find all matching suffixes and add the resulting words. ! * Additionally do matching prefixes that combine. */ if (store_aff_word(spin, dw, afflist, affile, &affile->af_suff, &affile->af_pref, CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) retval = FAIL; ! /* Find all matching prefixes and add the resulting words. */ if (store_aff_word(spin, dw, afflist, affile, &affile->af_pref, NULL, CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) --- 3631,3660 ---- need_affix = TRUE; if (affile->af_pfxpostpone) ! // Need to store the list of prefix IDs with the word. pfxlen = get_pfxlist(affile, afflist, store_afflist); if (spin->si_compflags != NULL) ! // Need to store the list of compound flags with the word. ! // Concatenate them to the list of prefix IDs. get_compflags(affile, afflist, store_afflist + pfxlen); } ! // Add the word to the word tree(s). if (store_word(spin, dw, flags, spin->si_region, store_afflist, need_affix) == FAIL) retval = FAIL; if (afflist != NULL) { ! // Find all matching suffixes and add the resulting words. ! // Additionally do matching prefixes that combine. if (store_aff_word(spin, dw, afflist, affile, &affile->af_suff, &affile->af_pref, CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) retval = FAIL; ! // Find all matching prefixes and add the resulting words. if (store_aff_word(spin, dw, afflist, affile, &affile->af_pref, NULL, CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) *************** *** 3729,3736 **** prevp = p; if (get_affitem(affile->af_flagtype, &p) != 0) { ! /* A flag is a postponed prefix flag if it appears in "af_pref" ! * and its ID is not zero. */ vim_strncpy(key, prevp, p - prevp); hi = hash_find(&affile->af_pref, key); if (!HASHITEM_EMPTY(hi)) --- 3729,3736 ---- prevp = p; if (get_affitem(affile->af_flagtype, &p) != 0) { ! // A flag is a postponed prefix flag if it appears in "af_pref" ! // and its ID is not zero. vim_strncpy(key, prevp, p - prevp); hi = hash_find(&affile->af_pref, key); if (!HASHITEM_EMPTY(hi)) *************** *** 3770,3776 **** prevp = p; if (get_affitem(affile->af_flagtype, &p) != 0) { ! /* A flag is a compound flag if it appears in "af_comp". */ vim_strncpy(key, prevp, p - prevp); hi = hash_find(&affile->af_comp, key); if (!HASHITEM_EMPTY(hi)) --- 3770,3776 ---- prevp = p; if (get_affitem(affile->af_flagtype, &p) != 0) { ! // A flag is a compound flag if it appears in "af_comp". vim_strncpy(key, prevp, p - prevp); hi = hash_find(&affile->af_comp, key); if (!HASHITEM_EMPTY(hi)) *************** *** 3794,3810 **** */ static int store_aff_word( ! spellinfo_T *spin, /* spell info */ ! char_u *word, /* basic word start */ ! char_u *afflist, /* list of names of supported affixes */ afffile_T *affile, hashtab_T *ht, hashtab_T *xht, ! int condit, /* CONDIT_SUF et al. */ ! int flags, /* flags for the word */ ! char_u *pfxlist, /* list of prefix IDs */ ! int pfxlen) /* nr of flags in "pfxlist" for prefixes, rest ! * is compound flags */ { int todo; hashitem_T *hi; --- 3794,3810 ---- */ static int store_aff_word( ! spellinfo_T *spin, // spell info ! char_u *word, // basic word start ! char_u *afflist, // list of names of supported affixes afffile_T *affile, hashtab_T *ht, hashtab_T *xht, ! int condit, // CONDIT_SUF et al. ! int flags, // flags for the word ! char_u *pfxlist, // list of prefix IDs ! int pfxlen) // nr of flags in "pfxlist" for prefixes, rest ! // is compound flags { int todo; hashitem_T *hi; *************** *** 3831,3855 **** --todo; ah = HI2AH(hi); ! /* Check that the affix combines, if required, and that the word ! * supports this affix. */ if (((condit & CONDIT_COMB) == 0 || ah->ah_combine) && flag_in_afflist(affile->af_flagtype, afflist, ah->ah_flag)) { ! /* Loop over all affix entries with this name. */ for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next) { ! /* Check the condition. It's not logical to match case ! * here, but it is required for compatibility with ! * Myspell. ! * Another requirement from Myspell is that the chop ! * string is shorter than the word itself. ! * For prefixes, when "PFXPOSTPONE" was used, only do ! * prefixes with a chop string and/or flags. ! * When a previously added affix had CIRCUMFIX this one ! * must have it too, if it had not then this one must not ! * have one either. */ if ((xht != NULL || !affile->af_pfxpostpone || ae->ae_chop != NULL || ae->ae_flags != NULL) --- 3831,3855 ---- --todo; ah = HI2AH(hi); ! // Check that the affix combines, if required, and that the word ! // supports this affix. if (((condit & CONDIT_COMB) == 0 || ah->ah_combine) && flag_in_afflist(affile->af_flagtype, afflist, ah->ah_flag)) { ! // Loop over all affix entries with this name. for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next) { ! // Check the condition. It's not logical to match case ! // here, but it is required for compatibility with ! // Myspell. ! // Another requirement from Myspell is that the chop ! // string is shorter than the word itself. ! // For prefixes, when "PFXPOSTPONE" was used, only do ! // prefixes with a chop string and/or flags. ! // When a previously added affix had CIRCUMFIX this one ! // must have it too, if it had not then this one must not ! // have one either. if ((xht != NULL || !affile->af_pfxpostpone || ae->ae_chop != NULL || ae->ae_flags != NULL) *************** *** 3864,3873 **** || !flag_in_afflist(affile->af_flagtype, ae->ae_flags, affile->af_circumfix)))) { ! /* Match. Remove the chop and add the affix. */ if (xht == NULL) { ! /* prefix: chop/add at the start of the word */ if (ae->ae_add == NULL) *newword = NUL; else --- 3864,3873 ---- || !flag_in_afflist(affile->af_flagtype, ae->ae_flags, affile->af_circumfix)))) { ! // Match. Remove the chop and add the affix. if (xht == NULL) { ! // prefix: chop/add at the start of the word if (ae->ae_add == NULL) *newword = NUL; else *************** *** 3875,3881 **** p = word; if (ae->ae_chop != NULL) { ! /* Skip chop string. */ if (has_mbyte) { i = mb_charlen(ae->ae_chop); --- 3875,3881 ---- p = word; if (ae->ae_chop != NULL) { ! // Skip chop string. if (has_mbyte) { i = mb_charlen(ae->ae_chop); *************** *** 3889,3899 **** } else { ! /* suffix: chop/add at the end of the word */ vim_strncpy(newword, word, MAXWLEN - 1); if (ae->ae_chop != NULL) { ! /* Remove chop string. */ p = newword + STRLEN(newword); i = (int)MB_CHARLEN(ae->ae_chop); for ( ; i > 0; --i) --- 3889,3899 ---- } else { ! // suffix: chop/add at the end of the word vim_strncpy(newword, word, MAXWLEN - 1); if (ae->ae_chop != NULL) { ! // Remove chop string. p = newword + STRLEN(newword); i = (int)MB_CHARLEN(ae->ae_chop); for ( ; i > 0; --i) *************** *** 3911,3917 **** use_condit = condit | CONDIT_COMB | CONDIT_AFF; if (ae->ae_flags != NULL) { ! /* Extract flags from the affix list. */ use_flags |= get_affix_flags(affile, ae->ae_flags); if (affile->af_needaffix != 0 && flag_in_afflist( --- 3911,3917 ---- use_condit = condit | CONDIT_COMB | CONDIT_AFF; if (ae->ae_flags != NULL) { ! // Extract flags from the affix list. use_flags |= get_affix_flags(affile, ae->ae_flags); if (affile->af_needaffix != 0 && flag_in_afflist( *************** *** 3919,3927 **** affile->af_needaffix)) need_affix = TRUE; ! /* When there is a CIRCUMFIX flag the other affix ! * must also have it and we don't add the word ! * with one affix. */ if (affile->af_circumfix != 0 && flag_in_afflist( affile->af_flagtype, ae->ae_flags, affile->af_circumfix)) --- 3919,3927 ---- affile->af_needaffix)) need_affix = TRUE; ! // When there is a CIRCUMFIX flag the other affix ! // must also have it and we don't add the word ! // with one affix. if (affile->af_circumfix != 0 && flag_in_afflist( affile->af_flagtype, ae->ae_flags, affile->af_circumfix)) *************** *** 3935,3949 **** || spin->si_compflags != NULL) { if (affile->af_pfxpostpone) ! /* Get prefix IDS from the affix list. */ use_pfxlen = get_pfxlist(affile, ae->ae_flags, store_afflist); else use_pfxlen = 0; use_pfxlist = store_afflist; ! /* Combine the prefix IDs. Avoid adding the ! * same ID twice. */ for (i = 0; i < pfxlen; ++i) { for (j = 0; j < use_pfxlen; ++j) --- 3935,3949 ---- || spin->si_compflags != NULL) { if (affile->af_pfxpostpone) ! // Get prefix IDS from the affix list. use_pfxlen = get_pfxlist(affile, ae->ae_flags, store_afflist); else use_pfxlen = 0; use_pfxlist = store_afflist; ! // Combine the prefix IDs. Avoid adding the ! // same ID twice. for (i = 0; i < pfxlen; ++i) { for (j = 0; j < use_pfxlen; ++j) *************** *** 3954,3966 **** } if (spin->si_compflags != NULL) ! /* Get compound IDS from the affix list. */ get_compflags(affile, ae->ae_flags, use_pfxlist + use_pfxlen); ! /* Combine the list of compound flags. ! * Concatenate them to the prefix IDs list. ! * Avoid adding the same ID twice. */ for (i = pfxlen; pfxlist[i] != NUL; ++i) { for (j = use_pfxlen; --- 3954,3966 ---- } if (spin->si_compflags != NULL) ! // Get compound IDS from the affix list. get_compflags(affile, ae->ae_flags, use_pfxlist + use_pfxlen); ! // Combine the list of compound flags. ! // Concatenate them to the prefix IDs list. ! // Avoid adding the same ID twice. for (i = pfxlen; pfxlist[i] != NUL; ++i) { for (j = use_pfxlen; *************** *** 3976,4006 **** } } ! /* Obey a "COMPOUNDFORBIDFLAG" of the affix: don't ! * use the compound flags. */ if (use_pfxlist != NULL && ae->ae_compforbid) { vim_strncpy(pfx_pfxlist, use_pfxlist, use_pfxlen); use_pfxlist = pfx_pfxlist; } ! /* When there are postponed prefixes... */ if (spin->si_prefroot != NULL && spin->si_prefroot->wn_sibling != NULL) { ! /* ... add a flag to indicate an affix was used. */ use_flags |= WF_HAS_AFF; ! /* ... don't use a prefix list if combining ! * affixes is not allowed. But do use the ! * compound flags after them. */ if (!ah->ah_combine && use_pfxlist != NULL) use_pfxlist += use_pfxlen; } ! /* When compounding is supported and there is no ! * "COMPOUNDPERMITFLAG" then forbid compounding on the ! * side where the affix is applied. */ if (spin->si_compflags != NULL && !ae->ae_comppermit) { if (xht != NULL) --- 3976,4006 ---- } } ! // Obey a "COMPOUNDFORBIDFLAG" of the affix: don't ! // use the compound flags. if (use_pfxlist != NULL && ae->ae_compforbid) { vim_strncpy(pfx_pfxlist, use_pfxlist, use_pfxlen); use_pfxlist = pfx_pfxlist; } ! // When there are postponed prefixes... if (spin->si_prefroot != NULL && spin->si_prefroot->wn_sibling != NULL) { ! // ... add a flag to indicate an affix was used. use_flags |= WF_HAS_AFF; ! // ... don't use a prefix list if combining ! // affixes is not allowed. But do use the ! // compound flags after them. if (!ah->ah_combine && use_pfxlist != NULL) use_pfxlist += use_pfxlen; } ! // When compounding is supported and there is no ! // "COMPOUNDPERMITFLAG" then forbid compounding on the ! // side where the affix is applied. if (spin->si_compflags != NULL && !ae->ae_comppermit) { if (xht != NULL) *************** *** 4009,4022 **** use_flags |= WF_NOCOMPBEF; } ! /* Store the modified word. */ if (store_word(spin, newword, use_flags, spin->si_region, use_pfxlist, need_affix) == FAIL) retval = FAIL; ! /* When added a prefix or a first suffix and the affix ! * has flags may add a(nother) suffix. RECURSIVE! */ if ((condit & CONDIT_SUF) && ae->ae_flags != NULL) if (store_aff_word(spin, newword, ae->ae_flags, affile, &affile->af_suff, xht, --- 4009,4022 ---- use_flags |= WF_NOCOMPBEF; } ! // Store the modified word. if (store_word(spin, newword, use_flags, spin->si_region, use_pfxlist, need_affix) == FAIL) retval = FAIL; ! // When added a prefix or a first suffix and the affix ! // has flags may add a(nother) suffix. RECURSIVE! if ((condit & CONDIT_SUF) && ae->ae_flags != NULL) if (store_aff_word(spin, newword, ae->ae_flags, affile, &affile->af_suff, xht, *************** *** 4025,4033 **** use_flags, use_pfxlist, pfxlen) == FAIL) retval = FAIL; ! /* When added a suffix and combining is allowed also ! * try adding a prefix additionally. Both for the ! * word flags and for the affix flags. RECURSIVE! */ if (xht != NULL && ah->ah_combine) { if (store_aff_word(spin, newword, --- 4025,4033 ---- use_flags, use_pfxlist, pfxlen) == FAIL) retval = FAIL; ! // When added a suffix and combining is allowed also ! // try adding a prefix additionally. Both for the ! // word flags and for the affix flags. RECURSIVE! if (xht != NULL && ah->ah_combine) { if (store_aff_word(spin, newword, *************** *** 4092,4110 **** line_breakcheck(); ++lnum; ! /* Skip comment lines. */ if (*rline == '#') continue; ! /* Remove CR, LF and white space from the end. */ l = (int)STRLEN(rline); while (l > 0 && rline[l - 1] <= ' ') --l; if (l == 0) ! continue; /* empty or blank line */ rline[l] = NUL; ! /* Convert from "/encoding={encoding}" to 'encoding' when needed. */ vim_free(pc); if (spin->si_conv.vc_type != CONV_NONE) { --- 4092,4110 ---- line_breakcheck(); ++lnum; ! // Skip comment lines. if (*rline == '#') continue; ! // Remove CR, LF and white space from the end. l = (int)STRLEN(rline); while (l > 0 && rline[l - 1] <= ' ') --l; if (l == 0) ! continue; // empty or blank line rline[l] = NUL; ! // Convert from "/encoding={encoding}" to 'encoding' when needed. vim_free(pc); if (spin->si_conv.vc_type != CONV_NONE) { *************** *** 4138,4144 **** { char_u *enc; ! /* Setup for conversion to 'encoding'. */ line += 9; enc = enc_canonize(line); if (enc != NULL && !spin->si_ascii --- 4138,4144 ---- { char_u *enc; ! // Setup for conversion to 'encoding'. line += 9; enc = enc_canonize(line); if (enc != NULL && !spin->si_ascii *************** *** 4168,4174 **** spin->si_region_count = (int)STRLEN(line) / 2; STRCPY(spin->si_region_name, line); ! /* Adjust the mask for a word valid in all regions. */ spin->si_region = (1 << spin->si_region_count) - 1; } } --- 4168,4174 ---- spin->si_region_count = (int)STRLEN(line) / 2; STRCPY(spin->si_region_name, line); ! // Adjust the mask for a word valid in all regions. spin->si_region = (1 << spin->si_region_count) - 1; } } *************** *** 4183,4204 **** flags = 0; regionmask = spin->si_region; ! /* Check for flags and region after a slash. */ p = vim_strchr(line, '/'); if (p != NULL) { *p++ = NUL; while (*p != NUL) { ! if (*p == '=') /* keep-case word */ flags |= WF_KEEPCAP | WF_FIXCAP; ! else if (*p == '!') /* Bad, bad, wicked word. */ flags |= WF_BANNED; ! else if (*p == '?') /* Rare word. */ flags |= WF_RARE; ! else if (VIM_ISDIGIT(*p)) /* region number(s) */ { ! if ((flags & WF_REGION) == 0) /* first one */ regionmask = 0; flags |= WF_REGION; --- 4183,4204 ---- flags = 0; regionmask = spin->si_region; ! // Check for flags and region after a slash. p = vim_strchr(line, '/'); if (p != NULL) { *p++ = NUL; while (*p != NUL) { ! if (*p == '=') // keep-case word flags |= WF_KEEPCAP | WF_FIXCAP; ! else if (*p == '!') // Bad, bad, wicked word. flags |= WF_BANNED; ! else if (*p == '?') // Rare word. flags |= WF_RARE; ! else if (VIM_ISDIGIT(*p)) // region number(s) { ! if ((flags & WF_REGION) == 0) // first one regionmask = 0; flags |= WF_REGION; *************** *** 4221,4234 **** } } ! /* Skip non-ASCII words when "spin->si_ascii" is TRUE. */ if (spin->si_ascii && has_non_ascii(line)) { ++non_ascii; continue; } ! /* Normal word: store it. */ if (store_word(spin, line, flags, regionmask, NULL, FALSE) == FAIL) { retval = FAIL; --- 4221,4234 ---- } } ! // Skip non-ASCII words when "spin->si_ascii" is TRUE. if (spin->si_ascii && has_non_ascii(line)) { ++non_ascii; continue; } ! // Normal word: store it. if (store_word(spin, line, flags, regionmask, NULL, FALSE) == FAIL) { retval = FAIL; *************** *** 4260,4274 **** static void * getroom( spellinfo_T *spin, ! size_t len, /* length needed */ ! int align) /* align for pointer */ { char_u *p; sblock_T *bl = spin->si_blocks; if (align && bl != NULL) ! /* Round size up for alignment. On some systems structures need to be ! * aligned to the size of a pointer (e.g., SPARC). */ bl->sb_used = (bl->sb_used + sizeof(char *) - 1) & ~(sizeof(char *) - 1); --- 4260,4274 ---- static void * getroom( spellinfo_T *spin, ! size_t len, // length needed ! int align) // align for pointer { char_u *p; sblock_T *bl = spin->si_blocks; if (align && bl != NULL) ! // Round size up for alignment. On some systems structures need to be ! // aligned to the size of a pointer (e.g., SPARC). bl->sb_used = (bl->sb_used + sizeof(char *) - 1) & ~(sizeof(char *) - 1); *************** *** 4277,4283 **** if (len >= SBLOCKSIZE) bl = NULL; else ! /* Allocate a block of memory. It is not freed until much later. */ bl = alloc_clear(sizeof(sblock_T) + SBLOCKSIZE); if (bl == NULL) { --- 4277,4283 ---- if (len >= SBLOCKSIZE) bl = NULL; else ! // Allocate a block of memory. It is not freed until much later. bl = alloc_clear(sizeof(sblock_T) + SBLOCKSIZE); if (bl == NULL) { *************** *** 4355,4364 **** store_word( spellinfo_T *spin, char_u *word, ! int flags, /* extra flags, WF_BANNED */ ! int region, /* supported region(s) */ ! char_u *pfxlist, /* list of prefix IDs or NULL */ ! int need_affix) /* only store word with affix ID */ { int len = (int)STRLEN(word); int ct = captype(word, word + len); --- 4355,4364 ---- store_word( spellinfo_T *spin, char_u *word, ! int flags, // extra flags, WF_BANNED ! int region, // supported region(s) ! char_u *pfxlist, // list of prefix IDs or NULL ! int need_affix) // only store word with affix ID { int len = (int)STRLEN(word); int ct = captype(word, word + len); *************** *** 4413,4437 **** wordnode_T **prev = NULL; int i; ! /* Add each byte of the word to the tree, including the NUL at the end. */ for (i = 0; ; ++i) { ! /* When there is more than one reference to this node we need to make ! * a copy, so that we can modify it. Copy the whole list of siblings ! * (we don't optimize for a partly shared list of siblings). */ if (node != NULL && node->wn_refs > 1) { --node->wn_refs; copyprev = prev; for (copyp = node; copyp != NULL; copyp = copyp->wn_sibling) { ! /* Allocate a new node and copy the info. */ np = get_wordnode(spin); if (np == NULL) return FAIL; np->wn_child = copyp->wn_child; if (np->wn_child != NULL) ! ++np->wn_child->wn_refs; /* child gets extra ref */ np->wn_byte = copyp->wn_byte; if (np->wn_byte == NUL) { --- 4413,4437 ---- wordnode_T **prev = NULL; int i; ! // Add each byte of the word to the tree, including the NUL at the end. for (i = 0; ; ++i) { ! // When there is more than one reference to this node we need to make ! // a copy, so that we can modify it. Copy the whole list of siblings ! // (we don't optimize for a partly shared list of siblings). if (node != NULL && node->wn_refs > 1) { --node->wn_refs; copyprev = prev; for (copyp = node; copyp != NULL; copyp = copyp->wn_sibling) { ! // Allocate a new node and copy the info. np = get_wordnode(spin); if (np == NULL) return FAIL; np->wn_child = copyp->wn_child; if (np->wn_child != NULL) ! ++np->wn_child->wn_refs; // child gets extra ref np->wn_byte = copyp->wn_byte; if (np->wn_byte == NUL) { *************** *** 4440,4461 **** np->wn_affixID = copyp->wn_affixID; } ! /* Link the new node in the list, there will be one ref. */ np->wn_refs = 1; if (copyprev != NULL) *copyprev = np; copyprev = &np->wn_sibling; ! /* Let "node" point to the head of the copied list. */ if (copyp == node) node = np; } } ! /* Look for the sibling that has the same character. They are sorted ! * on byte value, thus stop searching when a sibling is found with a ! * higher byte value. For zero bytes (end of word) the sorting is ! * done on flags and then on affixID. */ while (node != NULL && (node->wn_byte < word[i] || (node->wn_byte == NUL --- 4440,4461 ---- np->wn_affixID = copyp->wn_affixID; } ! // Link the new node in the list, there will be one ref. np->wn_refs = 1; if (copyprev != NULL) *copyprev = np; copyprev = &np->wn_sibling; ! // Let "node" point to the head of the copied list. if (copyp == node) node = np; } } ! // Look for the sibling that has the same character. They are sorted ! // on byte value, thus stop searching when a sibling is found with a ! // higher byte value. For zero bytes (end of word) the sorting is ! // done on flags and then on affixID. while (node != NULL && (node->wn_byte < word[i] || (node->wn_byte == NUL *************** *** 4479,4494 **** || node->wn_flags != (flags & WN_MASK) || node->wn_affixID != affixID))) { ! /* Allocate a new node. */ np = get_wordnode(spin); if (np == NULL) return FAIL; np->wn_byte = word[i]; ! /* If "node" is NULL this is a new child or the end of the sibling ! * list: ref count is one. Otherwise use ref count of sibling and ! * make ref count of sibling one (matters when inserting in front ! * of the list of siblings). */ if (node == NULL) np->wn_refs = 1; else --- 4479,4494 ---- || node->wn_flags != (flags & WN_MASK) || node->wn_affixID != affixID))) { ! // Allocate a new node. np = get_wordnode(spin); if (np == NULL) return FAIL; np->wn_byte = word[i]; ! // If "node" is NULL this is a new child or the end of the sibling ! // list: ref count is one. Otherwise use ref count of sibling and ! // make ref count of sibling one (matters when inserting in front ! // of the list of siblings). if (node == NULL) np->wn_refs = 1; else *************** *** 4517,4529 **** spell_print_tree(root->wn_sibling); #endif ! /* count nr of words added since last message */ ++spin->si_msg_count; if (spin->si_compress_cnt > 1) { if (--spin->si_compress_cnt == 1) ! /* Did enough words to lower the block count limit. */ spin->si_blocks_cnt += compress_inc; } --- 4517,4529 ---- spell_print_tree(root->wn_sibling); #endif ! // count nr of words added since last message ++spin->si_msg_count; if (spin->si_compress_cnt > 1) { if (--spin->si_compress_cnt == 1) ! // Did enough words to lower the block count limit. spin->si_blocks_cnt += compress_inc; } *************** *** 4545,4554 **** : spin->si_blocks_cnt >= compress_start) #endif { ! /* Decrement the block counter. The effect is that we compress again ! * when the freed up room has been used and another "compress_inc" ! * blocks have been allocated. Unless "compress_added" words have ! * been added, then the limit is put back again. */ spin->si_blocks_cnt -= compress_inc; spin->si_compress_cnt = compress_added; --- 4545,4554 ---- : spin->si_blocks_cnt >= compress_start) #endif { ! // Decrement the block counter. The effect is that we compress again ! // when the freed up room has been used and another "compress_inc" ! // blocks have been allocated. Unless "compress_added" words have ! // been added, then the limit is put back again. spin->si_blocks_cnt -= compress_inc; spin->si_compress_cnt = compress_added; *************** *** 4562,4571 **** out_flush(); } ! /* Compress both trees. Either they both have many nodes, which makes ! * compression useful, or one of them is small, which means ! * compression goes fast. But when filling the soundfold word tree ! * there is no keep-case tree. */ wordtree_compress(spin, spin->si_foldroot); if (affixID >= 0) wordtree_compress(spin, spin->si_keeproot); --- 4562,4571 ---- out_flush(); } ! // Compress both trees. Either they both have many nodes, which makes ! // compression useful, or one of them is small, which means ! // compression goes fast. But when filling the soundfold word tree ! // there is no keep-case tree. wordtree_compress(spin, spin->si_foldroot); if (affixID >= 0) wordtree_compress(spin, spin->si_keeproot); *************** *** 4621,4627 **** free_wordnode(spin, np); ++cnt; } ! ++cnt; /* length field */ } return cnt; } --- 4621,4627 ---- free_wordnode(spin, np); ++cnt; } ! ++cnt; // length field } return cnt; } *************** *** 4649,4656 **** int tot = 0; int perc; ! /* Skip the root itself, it's not actually used. The first sibling is the ! * start of the tree. */ if (root->wn_sibling != NULL) { hash_init(&ht); --- 4649,4656 ---- int tot = 0; int perc; ! // Skip the root itself, it's not actually used. The first sibling is the ! // start of the tree. if (root->wn_sibling != NULL) { hash_init(&ht); *************** *** 4687,4694 **** spellinfo_T *spin, wordnode_T *node, hashtab_T *ht, ! int *tot) /* total count of nodes before compressing, ! incremented while going through the tree */ { wordnode_T *np; wordnode_T *tp; --- 4687,4694 ---- spellinfo_T *spin, wordnode_T *node, hashtab_T *ht, ! int *tot) // total count of nodes before compressing, ! // incremented while going through the tree { wordnode_T *np; wordnode_T *tp; *************** *** 4710,4732 **** ++len; if ((child = np->wn_child) != NULL) { ! /* Compress the child first. This fills hashkey. */ compressed += node_compress(spin, child, ht, tot); ! /* Try to find an identical child. */ hash = hash_hash(child->wn_u1.hashkey); hi = hash_lookup(ht, child->wn_u1.hashkey, hash); if (!HASHITEM_EMPTY(hi)) { ! /* There are children we encountered before with a hash value ! * identical to the current child. Now check if there is one ! * that is really identical. */ for (tp = HI2WN(hi); tp != NULL; tp = tp->wn_u2.next) if (node_equal(child, tp)) { ! /* Found one! Now use that child in place of the ! * current one. This means the current child and all ! * its siblings is unlinked from the tree. */ ++tp->wn_refs; compressed += deref_wordnode(spin, child); np->wn_child = tp; --- 4710,4732 ---- ++len; if ((child = np->wn_child) != NULL) { ! // Compress the child first. This fills hashkey. compressed += node_compress(spin, child, ht, tot); ! // Try to find an identical child. hash = hash_hash(child->wn_u1.hashkey); hi = hash_lookup(ht, child->wn_u1.hashkey, hash); if (!HASHITEM_EMPTY(hi)) { ! // There are children we encountered before with a hash value ! // identical to the current child. Now check if there is one ! // that is really identical. for (tp = HI2WN(hi); tp != NULL; tp = tp->wn_u2.next) if (node_equal(child, tp)) { ! // Found one! Now use that child in place of the ! // current one. This means the current child and all ! // its siblings is unlinked from the tree. ++tp->wn_refs; compressed += deref_wordnode(spin, child); np->wn_child = tp; *************** *** 4734,4754 **** } if (tp == NULL) { ! /* No other child with this hash value equals the child of ! * the node, add it to the linked list after the first ! * item. */ tp = HI2WN(hi); child->wn_u2.next = tp->wn_u2.next; tp->wn_u2.next = child; } } else ! /* No other child has this hash value, add it to the ! * hashtable. */ hash_add_item(ht, hi, child->wn_u1.hashkey, hash); } } ! *tot += len + 1; /* add one for the node that stores the length */ /* * Make a hash key for the node and its siblings, so that we can quickly --- 4734,4754 ---- } if (tp == NULL) { ! // No other child with this hash value equals the child of ! // the node, add it to the linked list after the first ! // item. tp = HI2WN(hi); child->wn_u2.next = tp->wn_u2.next; tp->wn_u2.next = child; } } else ! // No other child has this hash value, add it to the ! // hashtable. hash_add_item(ht, hi, child->wn_u1.hashkey, hash); } } ! *tot += len + 1; // add one for the node that stores the length /* * Make a hash key for the node and its siblings, so that we can quickly *************** *** 4760,4774 **** for (np = node; np != NULL; np = np->wn_sibling) { if (np->wn_byte == NUL) ! /* end node: use wn_flags, wn_region and wn_affixID */ n = np->wn_flags + (np->wn_region << 8) + (np->wn_affixID << 16); else ! /* byte node: use the byte value and the child pointer */ n = (unsigned)(np->wn_byte + ((long_u)np->wn_child << 8)); nr = nr * 101 + n; } ! /* Avoid NUL bytes, it terminates the hash key. */ n = nr & 0xff; node->wn_u1.hashkey[1] = n == 0 ? 1 : n; n = (nr >> 8) & 0xff; --- 4760,4774 ---- for (np = node; np != NULL; np = np->wn_sibling) { if (np->wn_byte == NUL) ! // end node: use wn_flags, wn_region and wn_affixID n = np->wn_flags + (np->wn_region << 8) + (np->wn_affixID << 16); else ! // byte node: use the byte value and the child pointer n = (unsigned)(np->wn_byte + ((long_u)np->wn_child << 8)); nr = nr * 101 + n; } ! // Avoid NUL bytes, it terminates the hash key. n = nr & 0xff; node->wn_u1.hashkey[1] = n == 0 ? 1 : n; n = (nr >> 8) & 0xff; *************** *** 4779,4785 **** node->wn_u1.hashkey[4] = n == 0 ? 1 : n; node->wn_u1.hashkey[5] = NUL; ! /* Check for CTRL-C pressed now and then. */ fast_breakcheck(); return compressed; --- 4779,4785 ---- node->wn_u1.hashkey[4] = n == 0 ? 1 : n; node->wn_u1.hashkey[5] = NUL; ! // Check for CTRL-C pressed now and then. fast_breakcheck(); return compressed; *************** *** 4840,4847 **** char_u *p; int rr; int retval = OK; ! size_t fwv = 1; /* collect return value of fwrite() to avoid ! warnings from picky compiler */ fd = mch_fopen((char *)fname, "w"); if (fd == NULL) --- 4840,4847 ---- char_u *p; int rr; int retval = OK; ! size_t fwv = 1; // collect return value of fwrite() to avoid ! // warnings from picky compiler fd = mch_fopen((char *)fname, "w"); if (fd == NULL) *************** *** 4850,4913 **** return FAIL; } ! /*
: */ ! /* */ fwv &= fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, (size_t)1, fd); if (fwv != (size_t)1) ! /* Catch first write error, don't try writing more. */ goto theend; ! putc(VIMSPELLVERSION, fd); /* */ /* * :
... */ ! /* SN_INFO: */ if (spin->si_info != NULL) { ! putc(SN_INFO, fd); /* */ ! putc(0, fd); /* */ i = (int)STRLEN(spin->si_info); ! put_bytes(fd, (long_u)i, 4); /* */ ! fwv &= fwrite(spin->si_info, (size_t)i, (size_t)1, fd); /* */ } ! /* SN_REGION: ... ! * Write the region names only if there is more than one. */ if (spin->si_region_count > 1) { ! putc(SN_REGION, fd); /* */ ! putc(SNF_REQUIRED, fd); /* */ l = spin->si_region_count * 2; ! put_bytes(fd, (long_u)l, 4); /* */ fwv &= fwrite(spin->si_region_name, (size_t)l, (size_t)1, fd); ! /* ... */ regionmask = (1 << spin->si_region_count) - 1; } else regionmask = 0; ! /* SN_CHARFLAGS: ! * ! * The table with character flags and the table for case folding. ! * This makes sure the same characters are recognized as word characters ! * when generating an when using a spell file. ! * Skip this for ASCII, the table may conflict with the one used for ! * 'encoding'. ! * Also skip this for an .add.spl file, the main spell file must contain ! * the table (avoids that it conflicts). File is shorter too. ! */ if (!spin->si_ascii && !spin->si_add) { char_u folchars[128 * 8]; int flags; ! putc(SN_CHARFLAGS, fd); /* */ ! putc(SNF_REQUIRED, fd); /* */ ! /* Form the string first, we need to know its length. */ l = 0; for (i = 128; i < 256; ++i) { --- 4850,4912 ---- return FAIL; } ! //
: ! // fwv &= fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, (size_t)1, fd); if (fwv != (size_t)1) ! // Catch first write error, don't try writing more. goto theend; ! putc(VIMSPELLVERSION, fd); // /* * :
... */ ! // SN_INFO: if (spin->si_info != NULL) { ! putc(SN_INFO, fd); // ! putc(0, fd); // i = (int)STRLEN(spin->si_info); ! put_bytes(fd, (long_u)i, 4); // ! fwv &= fwrite(spin->si_info, (size_t)i, (size_t)1, fd); // } ! // SN_REGION: ... ! // Write the region names only if there is more than one. if (spin->si_region_count > 1) { ! putc(SN_REGION, fd); // ! putc(SNF_REQUIRED, fd); // l = spin->si_region_count * 2; ! put_bytes(fd, (long_u)l, 4); // fwv &= fwrite(spin->si_region_name, (size_t)l, (size_t)1, fd); ! // ... regionmask = (1 << spin->si_region_count) - 1; } else regionmask = 0; ! // SN_CHARFLAGS: ! // ! // The table with character flags and the table for case folding. ! // This makes sure the same characters are recognized as word characters ! // when generating an when using a spell file. ! // Skip this for ASCII, the table may conflict with the one used for ! // 'encoding'. ! // Also skip this for an .add.spl file, the main spell file must contain ! // the table (avoids that it conflicts). File is shorter too. if (!spin->si_ascii && !spin->si_add) { char_u folchars[128 * 8]; int flags; ! putc(SN_CHARFLAGS, fd); // ! putc(SNF_REQUIRED, fd); // ! // Form the string first, we need to know its length. l = 0; for (i = 128; i < 256; ++i) { *************** *** 4916,4924 **** else folchars[l++] = spelltab.st_fold[i]; } ! put_bytes(fd, (long_u)(1 + 128 + 2 + l), 4); /* */ ! fputc(128, fd); /* */ for (i = 128; i < 256; ++i) { flags = 0; --- 4915,4923 ---- else folchars[l++] = spelltab.st_fold[i]; } ! put_bytes(fd, (long_u)(1 + 128 + 2 + l), 4); // ! fputc(128, fd); // for (i = 128; i < 256; ++i) { flags = 0; *************** *** 4926,4976 **** flags |= CF_WORD; if (spelltab.st_isu[i]) flags |= CF_UPPER; ! fputc(flags, fd); /* */ } ! put_bytes(fd, (long_u)l, 2); /* */ ! fwv &= fwrite(folchars, (size_t)l, (size_t)1, fd); /* */ } ! /* SN_MIDWORD: */ if (spin->si_midword != NULL) { ! putc(SN_MIDWORD, fd); /* */ ! putc(SNF_REQUIRED, fd); /* */ i = (int)STRLEN(spin->si_midword); ! put_bytes(fd, (long_u)i, 4); /* */ fwv &= fwrite(spin->si_midword, (size_t)i, (size_t)1, fd); ! /* */ } ! /* SN_PREFCOND: ... */ if (spin->si_prefcond.ga_len > 0) { ! putc(SN_PREFCOND, fd); /* */ ! putc(SNF_REQUIRED, fd); /* */ l = write_spell_prefcond(NULL, &spin->si_prefcond); ! put_bytes(fd, (long_u)l, 4); /* */ write_spell_prefcond(fd, &spin->si_prefcond); } ! /* SN_REP: ... ! * SN_SAL: ... ! * SN_REPSAL: ... */ ! ! /* round 1: SN_REP section ! * round 2: SN_SAL section (unless SN_SOFO is used) ! * round 3: SN_REPSAL section */ for (round = 1; round <= 3; ++round) { if (round == 1) gap = &spin->si_rep; else if (round == 2) { ! /* Don't write SN_SAL when using a SN_SOFO section */ if (spin->si_sofofr != NULL && spin->si_sofoto != NULL) continue; gap = &spin->si_sal; --- 4925,4975 ---- flags |= CF_WORD; if (spelltab.st_isu[i]) flags |= CF_UPPER; ! fputc(flags, fd); // } ! put_bytes(fd, (long_u)l, 2); // ! fwv &= fwrite(folchars, (size_t)l, (size_t)1, fd); // } ! // SN_MIDWORD: if (spin->si_midword != NULL) { ! putc(SN_MIDWORD, fd); // ! putc(SNF_REQUIRED, fd); // i = (int)STRLEN(spin->si_midword); ! put_bytes(fd, (long_u)i, 4); // fwv &= fwrite(spin->si_midword, (size_t)i, (size_t)1, fd); ! // } ! // SN_PREFCOND: ... if (spin->si_prefcond.ga_len > 0) { ! putc(SN_PREFCOND, fd); // ! putc(SNF_REQUIRED, fd); // l = write_spell_prefcond(NULL, &spin->si_prefcond); ! put_bytes(fd, (long_u)l, 4); // write_spell_prefcond(fd, &spin->si_prefcond); } ! // SN_REP: ... ! // SN_SAL: ... ! // SN_REPSAL: ... ! ! // round 1: SN_REP section ! // round 2: SN_SAL section (unless SN_SOFO is used) ! // round 3: SN_REPSAL section for (round = 1; round <= 3; ++round) { if (round == 1) gap = &spin->si_rep; else if (round == 2) { ! // Don't write SN_SAL when using a SN_SOFO section if (spin->si_sofofr != NULL && spin->si_sofoto != NULL) continue; gap = &spin->si_sal; *************** *** 4978,5009 **** else gap = &spin->si_repsal; ! /* Don't write the section if there are no items. */ if (gap->ga_len == 0) continue; ! /* Sort the REP/REPSAL items. */ if (round != 2) qsort(gap->ga_data, (size_t)gap->ga_len, sizeof(fromto_T), rep_compare); i = round == 1 ? SN_REP : (round == 2 ? SN_SAL : SN_REPSAL); ! putc(i, fd); /* */ ! /* This is for making suggestions, section is not required. */ ! putc(0, fd); /* */ ! /* Compute the length of what follows. */ ! l = 2; /* count or */ for (i = 0; i < gap->ga_len; ++i) { ftp = &((fromto_T *)gap->ga_data)[i]; ! l += 1 + (int)STRLEN(ftp->ft_from); /* count <*fromlen> and <*from> */ ! l += 1 + (int)STRLEN(ftp->ft_to); /* count <*tolen> and <*to> */ } if (round == 2) ! ++l; /* count */ ! put_bytes(fd, (long_u)l, 4); /* */ if (round == 2) { --- 4977,5008 ---- else gap = &spin->si_repsal; ! // Don't write the section if there are no items. if (gap->ga_len == 0) continue; ! // Sort the REP/REPSAL items. if (round != 2) qsort(gap->ga_data, (size_t)gap->ga_len, sizeof(fromto_T), rep_compare); i = round == 1 ? SN_REP : (round == 2 ? SN_SAL : SN_REPSAL); ! putc(i, fd); // ! // This is for making suggestions, section is not required. ! putc(0, fd); // ! // Compute the length of what follows. ! l = 2; // count or for (i = 0; i < gap->ga_len; ++i) { ftp = &((fromto_T *)gap->ga_data)[i]; ! l += 1 + (int)STRLEN(ftp->ft_from); // count <*fromlen> and <*from> ! l += 1 + (int)STRLEN(ftp->ft_to); // count <*tolen> and <*to> } if (round == 2) ! ++l; // count ! put_bytes(fd, (long_u)l, 4); // if (round == 2) { *************** *** 5014,5027 **** i |= SAL_COLLAPSE; if (spin->si_rem_accents) i |= SAL_REM_ACCENTS; ! putc(i, fd); /* */ } ! put_bytes(fd, (long_u)gap->ga_len, 2); /* or */ for (i = 0; i < gap->ga_len; ++i) { ! /* : */ ! /* : */ ftp = &((fromto_T *)gap->ga_data)[i]; for (rr = 1; rr <= 2; ++rr) { --- 5013,5026 ---- i |= SAL_COLLAPSE; if (spin->si_rem_accents) i |= SAL_REM_ACCENTS; ! putc(i, fd); // } ! put_bytes(fd, (long_u)gap->ga_len, 2); // or for (i = 0; i < gap->ga_len; ++i) { ! // : ! // : ftp = &((fromto_T *)gap->ga_data)[i]; for (rr = 1; rr <= 2; ++rr) { *************** *** 5035,5068 **** } ! /* SN_SOFO: ! * This is for making suggestions, section is not required. */ if (spin->si_sofofr != NULL && spin->si_sofoto != NULL) { ! putc(SN_SOFO, fd); /* */ ! putc(0, fd); /* */ l = (int)STRLEN(spin->si_sofofr); put_bytes(fd, (long_u)(l + STRLEN(spin->si_sofoto) + 4), 4); ! /* */ ! put_bytes(fd, (long_u)l, 2); /* */ ! fwv &= fwrite(spin->si_sofofr, l, (size_t)1, fd); /* */ l = (int)STRLEN(spin->si_sofoto); ! put_bytes(fd, (long_u)l, 2); /* */ ! fwv &= fwrite(spin->si_sofoto, l, (size_t)1, fd); /* */ } ! /* SN_WORDS: ... ! * This is for making suggestions, section is not required. */ if (spin->si_commonwords.ht_used > 0) { ! putc(SN_WORDS, fd); /* */ ! putc(0, fd); /* */ ! /* round 1: count the bytes ! * round 2: write the bytes */ for (round = 1; round <= 2; ++round) { int todo; --- 5034,5067 ---- } ! // SN_SOFO: ! // This is for making suggestions, section is not required. if (spin->si_sofofr != NULL && spin->si_sofoto != NULL) { ! putc(SN_SOFO, fd); // ! putc(0, fd); // l = (int)STRLEN(spin->si_sofofr); put_bytes(fd, (long_u)(l + STRLEN(spin->si_sofoto) + 4), 4); ! // ! put_bytes(fd, (long_u)l, 2); // ! fwv &= fwrite(spin->si_sofofr, l, (size_t)1, fd); // l = (int)STRLEN(spin->si_sofoto); ! put_bytes(fd, (long_u)l, 2); // ! fwv &= fwrite(spin->si_sofoto, l, (size_t)1, fd); // } ! // SN_WORDS: ... ! // This is for making suggestions, section is not required. if (spin->si_commonwords.ht_used > 0) { ! putc(SN_WORDS, fd); // ! putc(0, fd); // ! // round 1: count the bytes ! // round 2: write the bytes for (round = 1; round <= 2; ++round) { int todo; *************** *** 5075,5197 **** { l = (int)STRLEN(hi->hi_key) + 1; len += l; ! if (round == 2) /* */ fwv &= fwrite(hi->hi_key, (size_t)l, (size_t)1, fd); --todo; } if (round == 1) ! put_bytes(fd, (long_u)len, 4); /* */ } } ! /* SN_MAP: ! * This is for making suggestions, section is not required. */ if (spin->si_map.ga_len > 0) { ! putc(SN_MAP, fd); /* */ ! putc(0, fd); /* */ l = spin->si_map.ga_len; ! put_bytes(fd, (long_u)l, 4); /* */ fwv &= fwrite(spin->si_map.ga_data, (size_t)l, (size_t)1, fd); ! /* */ } ! /* SN_SUGFILE: ! * This is used to notify that a .sug file may be available and at the ! * same time allows for checking that a .sug file that is found matches ! * with this .spl file. That's because the word numbers must be exactly ! * right. */ if (!spin->si_nosugfile && (spin->si_sal.ga_len > 0 || (spin->si_sofofr != NULL && spin->si_sofoto != NULL))) { ! putc(SN_SUGFILE, fd); /* */ ! putc(0, fd); /* */ ! put_bytes(fd, (long_u)8, 4); /* */ ! /* Set si_sugtime and write it to the file. */ spin->si_sugtime = time(NULL); ! put_time(fd, spin->si_sugtime); /* */ } ! /* SN_NOSPLITSUGS: nothing ! * This is used to notify that no suggestions with word splits are to be ! * made. */ if (spin->si_nosplitsugs) { ! putc(SN_NOSPLITSUGS, fd); /* */ ! putc(0, fd); /* */ ! put_bytes(fd, (long_u)0, 4); /* */ } ! /* SN_NOCOMPUNDSUGS: nothing ! * This is used to notify that no suggestions with compounds are to be ! * made. */ if (spin->si_nocompoundsugs) { ! putc(SN_NOCOMPOUNDSUGS, fd); /* */ ! putc(0, fd); /* */ ! put_bytes(fd, (long_u)0, 4); /* */ } ! /* SN_COMPOUND: compound info. ! * We don't mark it required, when not supported all compound words will ! * be bad words. */ if (spin->si_compflags != NULL) { ! putc(SN_COMPOUND, fd); /* */ ! putc(0, fd); /* */ l = (int)STRLEN(spin->si_compflags); for (i = 0; i < spin->si_comppat.ga_len; ++i) l += (int)STRLEN(((char_u **)(spin->si_comppat.ga_data))[i]) + 1; ! put_bytes(fd, (long_u)(l + 7), 4); /* */ ! putc(spin->si_compmax, fd); /* */ ! putc(spin->si_compminlen, fd); /* */ ! putc(spin->si_compsylmax, fd); /* */ ! putc(0, fd); /* for Vim 7.0b compatibility */ ! putc(spin->si_compoptions, fd); /* */ put_bytes(fd, (long_u)spin->si_comppat.ga_len, 2); ! /* */ for (i = 0; i < spin->si_comppat.ga_len; ++i) { p = ((char_u **)(spin->si_comppat.ga_data))[i]; ! putc((int)STRLEN(p), fd); /* */ fwv &= fwrite(p, (size_t)STRLEN(p), (size_t)1, fd); ! /* */ } ! /* */ fwv &= fwrite(spin->si_compflags, (size_t)STRLEN(spin->si_compflags), (size_t)1, fd); } ! /* SN_NOBREAK: NOBREAK flag */ if (spin->si_nobreak) { ! putc(SN_NOBREAK, fd); /* */ ! putc(0, fd); /* */ ! /* It's empty, the presence of the section flags the feature. */ ! put_bytes(fd, (long_u)0, 4); /* */ } ! /* SN_SYLLABLE: syllable info. ! * We don't mark it required, when not supported syllables will not be ! * counted. */ if (spin->si_syllable != NULL) { ! putc(SN_SYLLABLE, fd); /* */ ! putc(0, fd); /* */ l = (int)STRLEN(spin->si_syllable); ! put_bytes(fd, (long_u)l, 4); /* */ fwv &= fwrite(spin->si_syllable, (size_t)l, (size_t)1, fd); ! /* */ } ! /* end of */ ! putc(SN_END, fd); /* */ /* --- 5074,5196 ---- { l = (int)STRLEN(hi->hi_key) + 1; len += l; ! if (round == 2) // fwv &= fwrite(hi->hi_key, (size_t)l, (size_t)1, fd); --todo; } if (round == 1) ! put_bytes(fd, (long_u)len, 4); // } } ! // SN_MAP: ! // This is for making suggestions, section is not required. if (spin->si_map.ga_len > 0) { ! putc(SN_MAP, fd); // ! putc(0, fd); // l = spin->si_map.ga_len; ! put_bytes(fd, (long_u)l, 4); // fwv &= fwrite(spin->si_map.ga_data, (size_t)l, (size_t)1, fd); ! // } ! // SN_SUGFILE: ! // This is used to notify that a .sug file may be available and at the ! // same time allows for checking that a .sug file that is found matches ! // with this .spl file. That's because the word numbers must be exactly ! // right. if (!spin->si_nosugfile && (spin->si_sal.ga_len > 0 || (spin->si_sofofr != NULL && spin->si_sofoto != NULL))) { ! putc(SN_SUGFILE, fd); // ! putc(0, fd); // ! put_bytes(fd, (long_u)8, 4); // ! // Set si_sugtime and write it to the file. spin->si_sugtime = time(NULL); ! put_time(fd, spin->si_sugtime); // } ! // SN_NOSPLITSUGS: nothing ! // This is used to notify that no suggestions with word splits are to be ! // made. if (spin->si_nosplitsugs) { ! putc(SN_NOSPLITSUGS, fd); // ! putc(0, fd); // ! put_bytes(fd, (long_u)0, 4); // } ! // SN_NOCOMPUNDSUGS: nothing ! // This is used to notify that no suggestions with compounds are to be ! // made. if (spin->si_nocompoundsugs) { ! putc(SN_NOCOMPOUNDSUGS, fd); // ! putc(0, fd); // ! put_bytes(fd, (long_u)0, 4); // } ! // SN_COMPOUND: compound info. ! // We don't mark it required, when not supported all compound words will ! // be bad words. if (spin->si_compflags != NULL) { ! putc(SN_COMPOUND, fd); // ! putc(0, fd); // l = (int)STRLEN(spin->si_compflags); for (i = 0; i < spin->si_comppat.ga_len; ++i) l += (int)STRLEN(((char_u **)(spin->si_comppat.ga_data))[i]) + 1; ! put_bytes(fd, (long_u)(l + 7), 4); // ! putc(spin->si_compmax, fd); // ! putc(spin->si_compminlen, fd); // ! putc(spin->si_compsylmax, fd); // ! putc(0, fd); // for Vim 7.0b compatibility ! putc(spin->si_compoptions, fd); // put_bytes(fd, (long_u)spin->si_comppat.ga_len, 2); ! // for (i = 0; i < spin->si_comppat.ga_len; ++i) { p = ((char_u **)(spin->si_comppat.ga_data))[i]; ! putc((int)STRLEN(p), fd); // fwv &= fwrite(p, (size_t)STRLEN(p), (size_t)1, fd); ! // } ! // fwv &= fwrite(spin->si_compflags, (size_t)STRLEN(spin->si_compflags), (size_t)1, fd); } ! // SN_NOBREAK: NOBREAK flag if (spin->si_nobreak) { ! putc(SN_NOBREAK, fd); // ! putc(0, fd); // ! // It's empty, the presence of the section flags the feature. ! put_bytes(fd, (long_u)0, 4); // } ! // SN_SYLLABLE: syllable info. ! // We don't mark it required, when not supported syllables will not be ! // counted. if (spin->si_syllable != NULL) { ! putc(SN_SYLLABLE, fd); // ! putc(0, fd); // l = (int)STRLEN(spin->si_syllable); ! put_bytes(fd, (long_u)l, 4); // fwv &= fwrite(spin->si_syllable, (size_t)l, (size_t)1, fd); ! // } ! // end of ! putc(SN_END, fd); // /* *************** *** 5207,5229 **** else tree = spin->si_prefroot->wn_sibling; ! /* Clear the index and wnode fields in the tree. */ clear_node(tree); ! /* Count the number of nodes. Needed to be able to allocate the ! * memory when reading the nodes. Also fills in index for shared ! * nodes. */ nodecount = put_node(NULL, tree, 0, regionmask, round == 3); ! /* number of nodes in 4 bytes */ ! put_bytes(fd, (long_u)nodecount, 4); /* */ spin->si_memtot += nodecount + nodecount * sizeof(int); ! /* Write the nodes. */ (void)put_node(fd, tree, 0, regionmask, round == 3); } ! /* Write another byte to check for errors (file system full). */ if (putc(0, fd) == EOF) retval = FAIL; theend: --- 5206,5228 ---- else tree = spin->si_prefroot->wn_sibling; ! // Clear the index and wnode fields in the tree. clear_node(tree); ! // Count the number of nodes. Needed to be able to allocate the ! // memory when reading the nodes. Also fills in index for shared ! // nodes. nodecount = put_node(NULL, tree, 0, regionmask, round == 3); ! // number of nodes in 4 bytes ! put_bytes(fd, (long_u)nodecount, 4); // spin->si_memtot += nodecount + nodecount * sizeof(int); ! // Write the nodes. (void)put_node(fd, tree, 0, regionmask, round == 3); } ! // Write another byte to check for errors (file system full). if (putc(0, fd) == EOF) retval = FAIL; theend: *************** *** 5274,5332 **** */ static int put_node( ! FILE *fd, /* NULL when only counting */ wordnode_T *node, int idx, int regionmask, ! int prefixtree) /* TRUE for PREFIXTREE */ { int newindex = idx; int siblingcount = 0; wordnode_T *np; int flags; ! /* If "node" is zero the tree is empty. */ if (node == NULL) return 0; ! /* Store the index where this node is written. */ node->wn_u1.index = idx; ! /* Count the number of siblings. */ for (np = node; np != NULL; np = np->wn_sibling) ++siblingcount; ! /* Write the sibling count. */ if (fd != NULL) ! putc(siblingcount, fd); /* */ ! /* Write each sibling byte and optionally extra info. */ for (np = node; np != NULL; np = np->wn_sibling) { if (np->wn_byte == 0) { if (fd != NULL) { ! /* For a NUL byte (end of word) write the flags etc. */ if (prefixtree) { ! /* In PREFIXTREE write the required affixID and the ! * associated condition nr (stored in wn_region). The ! * byte value is misused to store the "rare" and "not ! * combining" flags */ if (np->wn_flags == (short_u)PFX_FLAGS) ! putc(BY_NOFLAGS, fd); /* */ else { ! putc(BY_FLAGS, fd); /* */ ! putc(np->wn_flags, fd); /* */ } ! putc(np->wn_affixID, fd); /* */ ! put_bytes(fd, (long_u)np->wn_region, 2); /* */ } else { ! /* For word trees we write the flag/region items. */ flags = np->wn_flags; if (regionmask != 0 && np->wn_region != regionmask) flags |= WF_REGION; --- 5273,5331 ---- */ static int put_node( ! FILE *fd, // NULL when only counting wordnode_T *node, int idx, int regionmask, ! int prefixtree) // TRUE for PREFIXTREE { int newindex = idx; int siblingcount = 0; wordnode_T *np; int flags; ! // If "node" is zero the tree is empty. if (node == NULL) return 0; ! // Store the index where this node is written. node->wn_u1.index = idx; ! // Count the number of siblings. for (np = node; np != NULL; np = np->wn_sibling) ++siblingcount; ! // Write the sibling count. if (fd != NULL) ! putc(siblingcount, fd); // ! // Write each sibling byte and optionally extra info. for (np = node; np != NULL; np = np->wn_sibling) { if (np->wn_byte == 0) { if (fd != NULL) { ! // For a NUL byte (end of word) write the flags etc. if (prefixtree) { ! // In PREFIXTREE write the required affixID and the ! // associated condition nr (stored in wn_region). The ! // byte value is misused to store the "rare" and "not ! // combining" flags if (np->wn_flags == (short_u)PFX_FLAGS) ! putc(BY_NOFLAGS, fd); // else { ! putc(BY_FLAGS, fd); // ! putc(np->wn_flags, fd); // } ! putc(np->wn_affixID, fd); // ! put_bytes(fd, (long_u)np->wn_region, 2); // } else { ! // For word trees we write the flag/region items. flags = np->wn_flags; if (regionmask != 0 && np->wn_region != regionmask) flags |= WF_REGION; *************** *** 5334,5359 **** flags |= WF_AFX; if (flags == 0) { ! /* word without flags or region */ ! putc(BY_NOFLAGS, fd); /* */ } else { if (np->wn_flags >= 0x100) { ! putc(BY_FLAGS2, fd); /* */ ! putc(flags, fd); /* */ ! putc((unsigned)flags >> 8, fd); /* */ } else { ! putc(BY_FLAGS, fd); /* */ ! putc(flags, fd); /* */ } if (flags & WF_REGION) ! putc(np->wn_region, fd); /* */ if (flags & WF_AFX) ! putc(np->wn_affixID, fd); /* */ } } } --- 5333,5358 ---- flags |= WF_AFX; if (flags == 0) { ! // word without flags or region ! putc(BY_NOFLAGS, fd); // } else { if (np->wn_flags >= 0x100) { ! putc(BY_FLAGS2, fd); // ! putc(flags, fd); // ! putc((unsigned)flags >> 8, fd); // } else { ! putc(BY_FLAGS, fd); // ! putc(flags, fd); // } if (flags & WF_REGION) ! putc(np->wn_region, fd); // if (flags & WF_AFX) ! putc(np->wn_affixID, fd); // } } } *************** *** 5363,5382 **** if (np->wn_child->wn_u1.index != 0 && np->wn_child->wn_u2.wnode != node) { ! /* The child is written elsewhere, write the reference. */ if (fd != NULL) { ! putc(BY_INDEX, fd); /* */ ! /* */ put_bytes(fd, (long_u)np->wn_child->wn_u1.index, 3); } } else if (np->wn_child->wn_u2.wnode == NULL) ! /* We will write the child below and give it an index. */ np->wn_child->wn_u2.wnode = node; if (fd != NULL) ! if (putc(np->wn_byte, fd) == EOF) /* or */ { emsg(_(e_write)); return 0; --- 5362,5381 ---- if (np->wn_child->wn_u1.index != 0 && np->wn_child->wn_u2.wnode != node) { ! // The child is written elsewhere, write the reference. if (fd != NULL) { ! putc(BY_INDEX, fd); // ! // put_bytes(fd, (long_u)np->wn_child->wn_u1.index, 3); } } else if (np->wn_child->wn_u2.wnode == NULL) ! // We will write the child below and give it an index. np->wn_child->wn_u2.wnode = node; if (fd != NULL) ! if (putc(np->wn_byte, fd) == EOF) // or { emsg(_(e_write)); return 0; *************** *** 5384,5394 **** } } ! /* Space used in the array when reading: one for each sibling and one for ! * the count. */ newindex += siblingcount + 1; ! /* Recursively dump the children of each sibling. */ for (np = node; np != NULL; np = np->wn_sibling) if (np->wn_byte != 0 && np->wn_child->wn_u2.wnode == node) newindex = put_node(fd, np->wn_child, newindex, regionmask, --- 5383,5393 ---- } } ! // Space used in the array when reading: one for each sibling and one for ! // the count. newindex += siblingcount + 1; ! // Recursively dump the children of each sibling. for (np = node; np != NULL; np = np->wn_sibling) if (np->wn_byte != 0 && np->wn_child->wn_u2.wnode == node) newindex = put_node(fd, np->wn_child, newindex, regionmask, *************** *** 5416,5422 **** arg = skipwhite(arg + 6); } ! /* Expand all the remaining arguments (e.g., $VIMRUNTIME). */ if (get_arglist_exp(arg, &fcount, &fnames, FALSE) == OK) { mkspell(fcount, fnames, ascii, eap->forceit, FALSE); --- 5415,5421 ---- arg = skipwhite(arg + 6); } ! // Expand all the remaining arguments (e.g., $VIMRUNTIME). if (get_arglist_exp(arg, &fcount, &fnames, FALSE) == OK) { mkspell(fcount, fnames, ascii, eap->forceit, FALSE); *************** *** 5461,5467 **** */ spin->si_blocks = NULL; spin->si_blocks_cnt = 0; ! spin->si_compress_cnt = 0; /* will stay at 0 all the time*/ spin->si_free_count = 0; spin->si_first_free = NULL; spin->si_foldwcount = 0; --- 5460,5466 ---- */ spin->si_blocks = NULL; spin->si_blocks_cnt = 0; ! spin->si_compress_cnt = 0; // will stay at 0 all the time spin->si_free_count = 0; spin->si_first_free = NULL; spin->si_foldwcount = 0; *************** *** 5531,5542 **** unsigned words_done = 0; int wordcount[MAXWLEN]; ! /* We use si_foldroot for the soundfolded trie. */ spin->si_foldroot = wordtree_alloc(spin); if (spin->si_foldroot == NULL) return FAIL; ! /* let tree_add_word() know we're adding to the soundfolded tree */ spin->si_sugtree = TRUE; /* --- 5530,5541 ---- unsigned words_done = 0; int wordcount[MAXWLEN]; ! // We use si_foldroot for the soundfolded trie. spin->si_foldroot = wordtree_alloc(spin); if (spin->si_foldroot == NULL) return FAIL; ! // let tree_add_word() know we're adding to the soundfolded tree spin->si_sugtree = TRUE; /* *************** *** 5555,5561 **** { if (curi[depth] > byts[arridx[depth]]) { ! /* Done all bytes at this node, go up one level. */ idxs[arridx[depth]] = wordcount[depth]; if (depth > 0) wordcount[depth - 1] += wordcount[depth]; --- 5554,5560 ---- { if (curi[depth] > byts[arridx[depth]]) { ! // Done all bytes at this node, go up one level. idxs[arridx[depth]] = wordcount[depth]; if (depth > 0) wordcount[depth - 1] += wordcount[depth]; *************** *** 5566,5584 **** else { ! /* Do one more byte at this node. */ n = arridx[depth] + curi[depth]; ++curi[depth]; c = byts[n]; if (c == 0) { ! /* Sound-fold the word. */ tword[depth] = NUL; spell_soundfold(slang, tword, TRUE, tsalword); ! /* We use the "flags" field for the MSB of the wordnr, ! * "region" for the LSB of the wordnr. */ if (tree_add_word(spin, tsalword, spin->si_foldroot, words_done >> 16, words_done & 0xffff, 0) == FAIL) --- 5565,5583 ---- else { ! // Do one more byte at this node. n = arridx[depth] + curi[depth]; ++curi[depth]; c = byts[n]; if (c == 0) { ! // Sound-fold the word. tword[depth] = NUL; spell_soundfold(slang, tword, TRUE, tsalword); ! // We use the "flags" field for the MSB of the wordnr, ! // "region" for the LSB of the wordnr. if (tree_add_word(spin, tsalword, spin->si_foldroot, words_done >> 16, words_done & 0xffff, 0) == FAIL) *************** *** 5587,5598 **** ++words_done; ++wordcount[depth]; ! /* Reset the block count each time to avoid compression ! * kicking in. */ spin->si_blocks_cnt = 0; ! /* Skip over any other NUL bytes (same word with different ! * flags). */ while (byts[n + 1] == 0) { ++n; --- 5586,5597 ---- ++words_done; ++wordcount[depth]; ! // Reset the block count each time to avoid compression ! // kicking in. spin->si_blocks_cnt = 0; ! // Skip over any other NUL bytes (same word with different ! // flags). while (byts[n + 1] == 0) { ++n; *************** *** 5601,5607 **** } else { ! /* Normal char, go one level deeper. */ tword[depth++] = c; arridx[depth] = idxs[n]; curi[depth] = 1; --- 5600,5606 ---- } else { ! // Normal char, go one level deeper. tword[depth++] = c; arridx[depth] = idxs[n]; curi[depth] = 1; *************** *** 5628,5644 **** garray_T ga; int res = OK; ! /* Allocate a buffer, open a memline for it and create the swap file ! * (uses a temp file, not a .swp file). */ spin->si_spellbuf = open_spellbuf(); if (spin->si_spellbuf == NULL) return FAIL; ! /* Use a buffer to store the line info, avoids allocating many small ! * pieces of memory. */ ga_init2(&ga, 1, 100); ! /* recursively go through the tree */ if (sug_filltable(spin, spin->si_foldroot->wn_sibling, 0, &ga) == -1) res = FAIL; --- 5627,5643 ---- garray_T ga; int res = OK; ! // Allocate a buffer, open a memline for it and create the swap file ! // (uses a temp file, not a .swp file). spin->si_spellbuf = open_spellbuf(); if (spin->si_spellbuf == NULL) return FAIL; ! // Use a buffer to store the line info, avoids allocating many small ! // pieces of memory. ga_init2(&ga, 1, 100); ! // recursively go through the tree if (sug_filltable(spin, spin->si_foldroot->wn_sibling, 0, &ga) == -1) res = FAIL; *************** *** 5656,5662 **** spellinfo_T *spin, wordnode_T *node, int startwordnr, ! garray_T *gap) /* place to store line of numbers */ { wordnode_T *p, *np; int wordnr = startwordnr; --- 5655,5661 ---- spellinfo_T *spin, wordnode_T *node, int startwordnr, ! garray_T *gap) // place to store line of numbers { wordnode_T *p, *np; int wordnr = startwordnr; *************** *** 5675,5691 **** return -1; nr = (np->wn_flags << 16) + (np->wn_region & 0xffff); ! /* Compute the offset from the previous nr and store the ! * offset in a way that it takes a minimum number of bytes. ! * It's a bit like utf-8, but without the need to mark ! * following bytes. */ nr -= prev_nr; prev_nr += nr; gap->ga_len += offset2bytes(nr, (char_u *)gap->ga_data + gap->ga_len); } ! /* add the NUL byte */ ((char_u *)gap->ga_data)[gap->ga_len++] = NUL; if (ml_append_buf(spin->si_spellbuf, (linenr_T)wordnr, --- 5674,5690 ---- return -1; nr = (np->wn_flags << 16) + (np->wn_region & 0xffff); ! // Compute the offset from the previous nr and store the ! // offset in a way that it takes a minimum number of bytes. ! // It's a bit like utf-8, but without the need to mark ! // following bytes. nr -= prev_nr; prev_nr += nr; gap->ga_len += offset2bytes(nr, (char_u *)gap->ga_data + gap->ga_len); } ! // add the NUL byte ((char_u *)gap->ga_data)[gap->ga_len++] = NUL; if (ml_append_buf(spin->si_spellbuf, (linenr_T)wordnr, *************** *** 5693,5705 **** return -1; ++wordnr; ! /* Remove extra NUL entries, we no longer need them. We don't ! * bother freeing the nodes, the won't be reused anyway. */ while (p->wn_sibling != NULL && p->wn_sibling->wn_byte == NUL) p->wn_sibling = p->wn_sibling->wn_sibling; ! /* Clear the flags on the remaining NUL node, so that compression ! * works a lot better. */ p->wn_flags = 0; p->wn_region = 0; } --- 5692,5704 ---- return -1; ++wordnr; ! // Remove extra NUL entries, we no longer need them. We don't ! // bother freeing the nodes, the won't be reused anyway. while (p->wn_sibling != NULL && p->wn_sibling->wn_byte == NUL) p->wn_sibling = p->wn_sibling->wn_sibling; ! // Clear the flags on the remaining NUL node, so that compression ! // works a lot better. p->wn_flags = 0; p->wn_region = 0; } *************** *** 5724,5730 **** int rem; int b1, b2, b3, b4; ! /* Split the number in parts of base 255. We need to avoid NUL bytes. */ b1 = nr % 255 + 1; rem = nr / 255; b2 = rem % 255 + 1; --- 5723,5729 ---- int rem; int b1, b2, b3, b4; ! // Split the number in parts of base 255. We need to avoid NUL bytes. b1 = nr % 255 + 1; rem = nr / 255; b2 = rem % 255 + 1; *************** *** 5732,5738 **** b3 = rem % 255 + 1; b4 = rem / 255 + 1; ! if (b4 > 1 || b3 > 0x1f) /* 4 bytes */ { buf[0] = 0xe0 + b4; buf[1] = b3; --- 5731,5737 ---- b3 = rem % 255 + 1; b4 = rem / 255 + 1; ! if (b4 > 1 || b3 > 0x1f) // 4 bytes { buf[0] = 0xe0 + b4; buf[1] = b3; *************** *** 5740,5759 **** buf[3] = b1; return 4; } ! if (b3 > 1 || b2 > 0x3f ) /* 3 bytes */ { buf[0] = 0xc0 + b3; buf[1] = b2; buf[2] = b1; return 3; } ! if (b2 > 1 || b1 > 0x7f ) /* 2 bytes */ { buf[0] = 0x80 + b2; buf[1] = b1; return 2; } ! /* 1 byte */ buf[0] = b1; return 1; } --- 5739,5758 ---- buf[3] = b1; return 4; } ! if (b3 > 1 || b2 > 0x3f ) // 3 bytes { buf[0] = 0xc0 + b3; buf[1] = b2; buf[2] = b1; return 3; } ! if (b2 > 1 || b1 > 0x7f ) // 2 bytes { buf[0] = 0x80 + b2; buf[1] = b1; return 2; } ! // 1 byte buf[0] = b1; return 1; } *************** *** 5772,5778 **** linenr_T lnum; int len; ! /* Create the file. Note that an existing file is silently overwritten! */ fd = mch_fopen((char *)fname, "w"); if (fd == NULL) { --- 5771,5777 ---- linenr_T lnum; int len; ! // Create the file. Note that an existing file is silently overwritten! fd = mch_fopen((char *)fname, "w"); if (fd == NULL) { *************** *** 5787,5801 **** /* * : */ ! if (fwrite(VIMSUGMAGIC, VIMSUGMAGICL, (size_t)1, fd) != 1) /* */ { emsg(_(e_write)); goto theend; } ! putc(VIMSUGVERSION, fd); /* */ ! /* Write si_sugtime to the file. */ ! put_time(fd, spin->si_sugtime); /* */ /* * --- 5786,5800 ---- /* * : */ ! if (fwrite(VIMSUGMAGIC, VIMSUGMAGICL, (size_t)1, fd) != 1) // { emsg(_(e_write)); goto theend; } ! putc(VIMSUGVERSION, fd); // ! // Write si_sugtime to the file. ! put_time(fd, spin->si_sugtime); // /* * *************** *** 5803,5832 **** spin->si_memtot = 0; tree = spin->si_foldroot->wn_sibling; ! /* Clear the index and wnode fields in the tree. */ clear_node(tree); ! /* Count the number of nodes. Needed to be able to allocate the ! * memory when reading the nodes. Also fills in index for shared ! * nodes. */ nodecount = put_node(NULL, tree, 0, 0, FALSE); ! /* number of nodes in 4 bytes */ ! put_bytes(fd, (long_u)nodecount, 4); /* */ spin->si_memtot += nodecount + nodecount * sizeof(int); ! /* Write the nodes. */ (void)put_node(fd, tree, 0, 0, FALSE); /* * : ... */ wcount = spin->si_spellbuf->b_ml.ml_line_count; ! put_bytes(fd, (long_u)wcount, 4); /* */ for (lnum = 1; lnum <= (linenr_T)wcount; ++lnum) { ! /* : ... NUL */ line = ml_get_buf(spin->si_spellbuf, lnum, FALSE); len = (int)STRLEN(line) + 1; if (fwrite(line, (size_t)len, (size_t)1, fd) == 0) --- 5802,5831 ---- spin->si_memtot = 0; tree = spin->si_foldroot->wn_sibling; ! // Clear the index and wnode fields in the tree. clear_node(tree); ! // Count the number of nodes. Needed to be able to allocate the ! // memory when reading the nodes. Also fills in index for shared ! // nodes. nodecount = put_node(NULL, tree, 0, 0, FALSE); ! // number of nodes in 4 bytes ! put_bytes(fd, (long_u)nodecount, 4); // spin->si_memtot += nodecount + nodecount * sizeof(int); ! // Write the nodes. (void)put_node(fd, tree, 0, 0, FALSE); /* * : ... */ wcount = spin->si_spellbuf->b_ml.ml_line_count; ! put_bytes(fd, (long_u)wcount, 4); // for (lnum = 1; lnum <= (linenr_T)wcount; ++lnum) { ! // : ... NUL line = ml_get_buf(spin->si_spellbuf, lnum, FALSE); len = (int)STRLEN(line) + 1; if (fwrite(line, (size_t)len, (size_t)1, fd) == 0) *************** *** 5837,5843 **** spin->si_memtot += len; } ! /* Write another byte to check for errors. */ if (putc(0, fd) == EOF) emsg(_(e_write)); --- 5836,5842 ---- spin->si_memtot += len; } ! // Write another byte to check for errors. if (putc(0, fd) == EOF) emsg(_(e_write)); *************** *** 5846,5852 **** spell_message(spin, IObuff); theend: ! /* close the file */ fclose(fd); } --- 5845,5851 ---- spell_message(spin, IObuff); theend: ! // close the file fclose(fd); } *************** *** 5862,5870 **** mkspell( int fcount, char_u **fnames, ! int ascii, /* -ascii argument given */ ! int over_write, /* overwrite existing output file */ ! int added_word) /* invoked through "zg" */ { char_u *fname = NULL; char_u *wfname; --- 5861,5869 ---- mkspell( int fcount, char_u **fnames, ! int ascii, // -ascii argument given ! int over_write, // overwrite existing output file ! int added_word) // invoked through "zg" { char_u *fname = NULL; char_u *wfname; *************** *** 5889,5897 **** ga_init2(&spin.si_comppat, (int)sizeof(char_u *), 20); ga_init2(&spin.si_prefcond, (int)sizeof(char_u *), 50); hash_init(&spin.si_commonwords); ! spin.si_newcompID = 127; /* start compound ID at first maximum */ ! /* default: fnames[0] is output file, following are input files */ innames = &fnames[1]; incount = fcount - 1; --- 5888,5896 ---- ga_init2(&spin.si_comppat, (int)sizeof(char_u *), 20); ga_init2(&spin.si_prefcond, (int)sizeof(char_u *), 50); hash_init(&spin.si_commonwords); ! spin.si_newcompID = 127; // start compound ID at first maximum ! // default: fnames[0] is output file, following are input files innames = &fnames[1]; incount = fcount - 1; *************** *** 5904,5918 **** len = (int)STRLEN(fnames[0]); if (fcount == 1 && len > 4 && STRCMP(fnames[0] + len - 4, ".add") == 0) { ! /* For ":mkspell path/en.latin1.add" output file is ! * "path/en.latin1.add.spl". */ innames = &fnames[0]; incount = 1; vim_snprintf((char *)wfname, MAXPATHL, "%s.spl", fnames[0]); } else if (fcount == 1) { ! /* For ":mkspell path/vim" output file is "path/vim.latin1.spl". */ innames = &fnames[0]; incount = 1; vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL, --- 5903,5917 ---- len = (int)STRLEN(fnames[0]); if (fcount == 1 && len > 4 && STRCMP(fnames[0] + len - 4, ".add") == 0) { ! // For ":mkspell path/en.latin1.add" output file is ! // "path/en.latin1.add.spl". innames = &fnames[0]; incount = 1; vim_snprintf((char *)wfname, MAXPATHL, "%s.spl", fnames[0]); } else if (fcount == 1) { ! // For ":mkspell path/vim" output file is "path/vim.latin1.spl". innames = &fnames[0]; incount = 1; vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL, *************** *** 5920,5952 **** } else if (len > 4 && STRCMP(fnames[0] + len - 4, ".spl") == 0) { ! /* Name ends in ".spl", use as the file name. */ vim_strncpy(wfname, fnames[0], MAXPATHL - 1); } else ! /* Name should be language, make the file name from it. */ vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL, fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc()); ! /* Check for .ascii.spl. */ if (strstr((char *)gettail(wfname), SPL_FNAME_ASCII) != NULL) spin.si_ascii = TRUE; ! /* Check for .add.spl. */ if (strstr((char *)gettail(wfname), SPL_FNAME_ADD) != NULL) spin.si_add = TRUE; } if (incount <= 0) ! emsg(_(e_invarg)); /* need at least output and input names */ else if (vim_strchr(gettail(wfname), '_') != NULL) emsg(_("E751: Output file name must not have region name")); else if (incount > MAXREGIONS) semsg(_("E754: Only up to %d regions supported"), MAXREGIONS); else { ! /* Check for overwriting before doing things that may take a lot of ! * time. */ if (!over_write && mch_stat((char *)wfname, &st) >= 0) { emsg(_(e_exists)); --- 5919,5951 ---- } else if (len > 4 && STRCMP(fnames[0] + len - 4, ".spl") == 0) { ! // Name ends in ".spl", use as the file name. vim_strncpy(wfname, fnames[0], MAXPATHL - 1); } else ! // Name should be language, make the file name from it. vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL, fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc()); ! // Check for .ascii.spl. if (strstr((char *)gettail(wfname), SPL_FNAME_ASCII) != NULL) spin.si_ascii = TRUE; ! // Check for .add.spl. if (strstr((char *)gettail(wfname), SPL_FNAME_ADD) != NULL) spin.si_add = TRUE; } if (incount <= 0) ! emsg(_(e_invarg)); // need at least output and input names else if (vim_strchr(gettail(wfname), '_') != NULL) emsg(_("E751: Output file name must not have region name")); else if (incount > MAXREGIONS) semsg(_("E754: Only up to %d regions supported"), MAXREGIONS); else { ! // Check for overwriting before doing things that may take a lot of ! // time. if (!over_write && mch_stat((char *)wfname, &st) >= 0) { emsg(_(e_exists)); *************** *** 5997,6007 **** goto theend; } ! /* When not producing a .add.spl file clear the character table when ! * we encounter one in the .aff file. This means we dump the current ! * one in the .spl file if the .aff file doesn't define one. That's ! * better than guessing the contents, the table will match a ! * previously loaded spell file. */ if (!spin.si_add) spin.si_clear_chartab = TRUE; --- 5996,6006 ---- goto theend; } ! // When not producing a .add.spl file clear the character table when ! // we encounter one in the .aff file. This means we dump the current ! // one in the .spl file if the .aff file doesn't define one. That's ! // better than guessing the contents, the table will match a ! // previously loaded spell file. if (!spin.si_add) spin.si_clear_chartab = TRUE; *************** *** 6018,6031 **** vim_snprintf((char *)fname, MAXPATHL, "%s.aff", innames[i]); if (mch_stat((char *)fname, &st) >= 0) { ! /* Read the .aff file. Will init "spin->si_conv" based on the ! * "SET" line. */ afile[i] = spell_read_aff(&spin, fname); if (afile[i] == NULL) error = TRUE; else { ! /* Read the .dic file and store the words in the trees. */ vim_snprintf((char *)fname, MAXPATHL, "%s.dic", innames[i]); if (spell_read_dic(&spin, fname, afile[i]) == FAIL) --- 6017,6030 ---- vim_snprintf((char *)fname, MAXPATHL, "%s.aff", innames[i]); if (mch_stat((char *)fname, &st) >= 0) { ! // Read the .aff file. Will init "spin->si_conv" based on the ! // "SET" line. afile[i] = spell_read_aff(&spin, fname); if (afile[i] == NULL) error = TRUE; else { ! // Read the .dic file and store the words in the trees. vim_snprintf((char *)fname, MAXPATHL, "%s.dic", innames[i]); if (spell_read_dic(&spin, fname, afile[i]) == FAIL) *************** *** 6034,6046 **** } else { ! /* No .aff file, try reading the file as a word list. Store ! * the words in the trees. */ if (spell_read_wordfile(&spin, innames[i]) == FAIL) error = TRUE; } ! /* Free any conversion stuff. */ convert_setup(&spin.si_conv, NULL, NULL); } --- 6033,6045 ---- } else { ! // No .aff file, try reading the file as a word list. Store ! // the words in the trees. if (spell_read_wordfile(&spin, innames[i]) == FAIL) error = TRUE; } ! // Free any conversion stuff. convert_setup(&spin.si_conv, NULL, NULL); } *************** *** 6081,6087 **** spell_reload_one(wfname, added_word); } ! /* Free the allocated memory. */ ga_clear(&spin.si_rep); ga_clear(&spin.si_repsal); ga_clear(&spin.si_sal); --- 6080,6086 ---- spell_reload_one(wfname, added_word); } ! // Free the allocated memory. ga_clear(&spin.si_rep); ga_clear(&spin.si_repsal); ga_clear(&spin.si_sal); *************** *** 6090,6101 **** ga_clear(&spin.si_prefcond); hash_clear_all(&spin.si_commonwords, 0); ! /* Free the .aff file structures. */ for (i = 0; i < incount; ++i) if (afile[i] != NULL) spell_free_aff(afile[i]); ! /* Free all the bits and pieces at once. */ free_blocks(spin.si_blocks); /* --- 6089,6100 ---- ga_clear(&spin.si_prefcond); hash_clear_all(&spin.si_commonwords, 0); ! // Free the .aff file structures. for (i = 0; i < incount; ++i) if (afile[i] != NULL) spell_free_aff(afile[i]); ! // Free all the bits and pieces at once. free_blocks(spin.si_blocks); /* *************** *** 6168,6174 **** int i; char_u *spf; ! if (idx == 0) /* use internal wordlist */ { if (int_wordlist == NULL) { --- 6167,6173 ---- int i; char_u *spf; ! if (idx == 0) // use internal wordlist { if (int_wordlist == NULL) { *************** *** 6180,6186 **** } else { ! /* If 'spellfile' isn't set figure out a good default value. */ if (*curwin->w_s->b_p_spf == NUL) { init_spellfile(); --- 6179,6185 ---- } else { ! // If 'spellfile' isn't set figure out a good default value. if (*curwin->w_s->b_p_spf == NUL) { init_spellfile(); *************** *** 6209,6215 **** } } ! /* Check that the user isn't editing the .add file somewhere. */ buf = buflist_findname_exp(fnamebuf); if (buf != NULL && buf->b_ml.ml_mfp == NULL) buf = NULL; --- 6208,6214 ---- } } ! // Check that the user isn't editing the .add file somewhere. buf = buflist_findname_exp(fnamebuf); if (buf != NULL && buf->b_ml.ml_mfp == NULL) buf = NULL; *************** *** 6225,6232 **** if (what == SPELL_ADD_BAD || undo) { ! /* When the word appears as good word we need to remove that one, ! * since its flags sort before the one with WF_BANNED. */ fd = mch_fopen((char *)fname, "r"); if (fd != NULL) { --- 6224,6231 ---- if (what == SPELL_ADD_BAD || undo) { ! // When the word appears as good word we need to remove that one, ! // since its flags sort before the one with WF_BANNED. fd = mch_fopen((char *)fname, "r"); if (fd != NULL) { *************** *** 6237,6245 **** if (STRNCMP(word, line, len) == 0 && (line[len] == '/' || line[len] < ' ')) { ! /* Found duplicate word. Remove it by writing a '#' at ! * the start of the line. Mixing reading and writing ! * doesn't work for all systems, close the file first. */ fclose(fd); fd = mch_fopen((char *)fname, "r+"); if (fd == NULL) --- 6236,6244 ---- if (STRNCMP(word, line, len) == 0 && (line[len] == '/' || line[len] < ' ')) { ! // Found duplicate word. Remove it by writing a '#' at ! // the start of the line. Mixing reading and writing ! // doesn't work for all systems, close the file first. fclose(fd); fd = mch_fopen((char *)fname, "r+"); if (fd == NULL) *************** *** 6269,6284 **** { char_u *p; ! /* We just initialized the 'spellfile' option and can't open the ! * file. We may need to create the "spell" directory first. We ! * already checked the runtime directory is writable in ! * init_spellfile(). */ if (!dir_of_file_exists(fname) && (p = gettail_sep(fname)) != fname) { int c = *p; ! /* The directory doesn't exist. Try creating it and opening ! * the file again. */ *p = NUL; vim_mkdir(fname, 0755); *p = c; --- 6268,6283 ---- { char_u *p; ! // We just initialized the 'spellfile' option and can't open the ! // file. We may need to create the "spell" directory first. We ! // already checked the runtime directory is writable in ! // init_spellfile(). if (!dir_of_file_exists(fname) && (p = gettail_sep(fname)) != fname) { int c = *p; ! // The directory doesn't exist. Try creating it and opening ! // the file again. *p = NUL; vim_mkdir(fname, 0755); *p = c; *************** *** 6305,6314 **** if (fd != NULL) { ! /* Update the .add.spl file. */ mkspell(1, &fname, FALSE, TRUE, TRUE); ! /* If the .add file is edited somewhere, reload it. */ if (buf != NULL) buf_reload(buf, buf->b_orig_mode); --- 6304,6313 ---- if (fd != NULL) { ! // Update the .add.spl file. mkspell(1, &fname, FALSE, TRUE, TRUE); ! // If the .add file is edited somewhere, reload it. if (buf != NULL) buf_reload(buf, buf->b_orig_mode); *************** *** 6337,6344 **** if (buf == NULL) return; ! /* Find the end of the language name. Exclude the region. If there ! * is a path separator remember the start of the tail. */ for (lend = curwin->w_s->b_p_spl; *lend != NUL && vim_strchr((char_u *)",._", *lend) == NULL; ++lend) if (vim_ispathsep(*lend)) --- 6336,6343 ---- if (buf == NULL) return; ! // Find the end of the language name. Exclude the region. If there ! // is a path separator remember the start of the tail. for (lend = curwin->w_s->b_p_spl; *lend != NUL && vim_strchr((char_u *)",._", *lend) == NULL; ++lend) if (vim_ispathsep(*lend)) *************** *** 6347,6375 **** lstart = lend + 1; } ! /* Loop over all entries in 'runtimepath'. Use the first one where we ! * are allowed to write. */ rtp = p_rtp; while (*rtp != NUL) { if (aspath) ! /* Use directory of an entry with path, e.g., for ! * "/dir/lg.utf-8.spl" use "/dir". */ vim_strncpy(buf, curbuf->b_s.b_p_spl, lstart - curbuf->b_s.b_p_spl - 1); else ! /* Copy the path from 'runtimepath' to buf[]. */ copy_option_part(&rtp, buf, MAXPATHL, ","); if (filewritable(buf) == 2) { ! /* Use the first language name from 'spelllang' and the ! * encoding used in the first loaded .spl file. */ if (aspath) vim_strncpy(buf, curbuf->b_s.b_p_spl, lend - curbuf->b_s.b_p_spl); else { ! /* Create the "spell" directory if it doesn't exist yet. */ l = (int)STRLEN(buf); vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell"); if (filewritable(buf) != 2) --- 6346,6374 ---- lstart = lend + 1; } ! // Loop over all entries in 'runtimepath'. Use the first one where we ! // are allowed to write. rtp = p_rtp; while (*rtp != NUL) { if (aspath) ! // Use directory of an entry with path, e.g., for ! // "/dir/lg.utf-8.spl" use "/dir". vim_strncpy(buf, curbuf->b_s.b_p_spl, lstart - curbuf->b_s.b_p_spl - 1); else ! // Copy the path from 'runtimepath' to buf[]. copy_option_part(&rtp, buf, MAXPATHL, ","); if (filewritable(buf) == 2) { ! // Use the first language name from 'spelllang' and the ! // encoding used in the first loaded .spl file. if (aspath) vim_strncpy(buf, curbuf->b_s.b_p_spl, lend - curbuf->b_s.b_p_spl); else { ! // Create the "spell" directory if it doesn't exist yet. l = (int)STRLEN(buf); vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell"); if (filewritable(buf) != 2) *************** *** 6404,6411 **** static int set_spell_chartab(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; --- 6403,6410 ---- static int set_spell_chartab(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; *************** *** 6423,6429 **** l = mb_ptr2char_adv(&pl); u = mb_ptr2char_adv(&pu); ! /* Every character that appears is a word character. */ if (f < 256) new_st.st_isw[f] = TRUE; if (l < 256) --- 6422,6428 ---- l = mb_ptr2char_adv(&pl); u = mb_ptr2char_adv(&pu); ! // Every character that appears is a word character. if (f < 256) new_st.st_isw[f] = TRUE; if (l < 256) *************** *** 6431,6438 **** 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) --- 6430,6437 ---- 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) *************** *** 6443,6451 **** new_st.st_fold[l] = f; } ! /* if "UPP" and "FOL" are not the same the "UPP" char needs ! * case-folding, it's upper case and the "UPP" is the upper case of ! * "FOL" . */ if (u < 256 && u != f) { if (f >= 256) --- 6442,6450 ---- new_st.st_fold[l] = f; } ! // if "UPP" and "FOL" are not the same the "UPP" char needs ! // case-folding, it's upper case and the "UPP" is the upper case of ! // "FOL" . if (u < 256 && u != f) { if (f >= 256) *************** *** 6474,6484 **** static void set_spell_charflags( char_u *flags, ! int cnt, /* length of "flags" */ char_u *fol) { ! /* 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 = fol; --- 6473,6483 ---- static void set_spell_charflags( char_u *flags, ! int cnt, // length of "flags" char_u *fol) { ! // 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 = fol; *************** *** 6513,6519 **** if (did_set_spelltab) { ! /* check that it's the same table */ for (i = 0; i < 256; ++i) { if (spelltab.st_isw[i] != new_st->st_isw[i] --- 6512,6518 ---- if (did_set_spelltab) { ! // check that it's the same table for (i = 0; i < 256; ++i) { if (spelltab.st_isw[i] != new_st->st_isw[i] *************** *** 6528,6534 **** } else { ! /* copy the new spelltab into the one being used */ spelltab = *new_st; did_set_spelltab = TRUE; } --- 6527,6533 ---- } else { ! // copy the new spelltab into the one being used spelltab = *new_st; did_set_spelltab = TRUE; } *************** *** 6547,6562 **** char_u *p; int len; int totlen; ! size_t x = 1; /* collect return value of fwrite() */ if (fd != NULL) ! put_bytes(fd, (long_u)gap->ga_len, 2); /* */ ! totlen = 2 + gap->ga_len; /* length of and bytes */ for (i = 0; i < gap->ga_len; ++i) { ! /* : */ p = ((char_u **)gap->ga_data)[i]; if (p != NULL) { --- 6546,6561 ---- char_u *p; int len; int totlen; ! size_t x = 1; // collect return value of fwrite() if (fd != NULL) ! put_bytes(fd, (long_u)gap->ga_len, 2); // ! totlen = 2 + gap->ga_len; // length of and bytes for (i = 0; i < gap->ga_len; ++i) { ! // : p = ((char_u **)gap->ga_data)[i]; if (p != NULL) { *************** *** 6594,6600 **** } lp->sl_has_map = TRUE; ! /* Init the array and hash tables empty. */ for (i = 0; i < 256; ++i) lp->sl_map_array[i] = 0; hash_init(&lp->sl_map_hash); --- 6593,6599 ---- } lp->sl_has_map = TRUE; ! // Init the array and hash tables empty. for (i = 0; i < 256; ++i) lp->sl_map_array[i] = 0; hash_init(&lp->sl_map_hash); *************** *** 6614,6622 **** if (headc == 0) headc = c; ! /* Characters above 255 don't fit in sl_map_array[], put them in ! * the hash table. Each entry is the char, a NUL the headchar and ! * a NUL. */ if (c >= 256) { int cl = mb_char2len(c); --- 6613,6621 ---- if (headc == 0) headc = c; ! // Characters above 255 don't fit in sl_map_array[], put them in ! // the hash table. Each entry is the char, a NUL the headchar and ! // a NUL. if (c >= 256) { int cl = mb_char2len(c); *************** *** 6638,6645 **** hash_add_item(&lp->sl_map_hash, hi, b, hash); else { ! /* This should have been checked when generating the .spl ! * file. */ emsg(_("E783: duplicate char in MAP entry")); vim_free(b); } --- 6637,6644 ---- hash_add_item(&lp->sl_map_hash, hi, b, hash); else { ! // This should have been checked when generating the .spl ! // file. emsg(_("E783: duplicate char in MAP entry")); vim_free(b); } *************** *** 6651,6654 **** } ! #endif /* FEAT_SPELL */ --- 6650,6653 ---- } ! #endif // FEAT_SPELL *** ../vim-8.1.2394/src/syntax.c 2019-08-31 15:27:59.001773229 +0200 --- src/syntax.c 2019-12-05 21:23:36.272852815 +0100 *************** *** 15,30 **** #if defined(FEAT_SYN_HL) || defined(PROTO) ! #define SYN_NAMELEN 50 /* maximum length of a syntax name */ ! /* different types of offsets that are possible */ ! #define SPO_MS_OFF 0 /* match start offset */ ! #define SPO_ME_OFF 1 /* match end offset */ ! #define SPO_HS_OFF 2 /* highl. start offset */ ! #define SPO_HE_OFF 3 /* highl. end offset */ ! #define SPO_RS_OFF 4 /* region start offset */ ! #define SPO_RE_OFF 5 /* region end offset */ ! #define SPO_LC_OFF 6 /* leading context offset */ #define SPO_COUNT 7 static char *(spo_name_tab[SPO_COUNT]) = --- 15,30 ---- #if defined(FEAT_SYN_HL) || defined(PROTO) ! #define SYN_NAMELEN 50 // maximum length of a syntax name ! // different types of offsets that are possible ! #define SPO_MS_OFF 0 // match start offset ! #define SPO_ME_OFF 1 // match end offset ! #define SPO_HS_OFF 2 // highl. start offset ! #define SPO_HE_OFF 3 // highl. end offset ! #define SPO_RS_OFF 4 // region start offset ! #define SPO_RE_OFF 5 // region end offset ! #define SPO_LC_OFF 6 // leading context offset #define SPO_COUNT 7 static char *(spo_name_tab[SPO_COUNT]) = *************** *** 45,106 **** */ typedef struct syn_pattern { ! char sp_type; /* see SPTYPE_ defines below */ ! char sp_syncing; /* this item used for syncing */ ! short sp_syn_match_id; /* highlight group ID of pattern */ ! short sp_off_flags; /* see below */ ! int sp_offsets[SPO_COUNT]; /* offsets */ ! int sp_flags; /* see HL_ defines below */ #ifdef FEAT_CONCEAL ! int sp_cchar; /* conceal substitute character */ #endif ! int sp_ic; /* ignore-case flag for sp_prog */ ! int sp_sync_idx; /* sync item index (syncing only) */ ! int sp_line_id; /* ID of last line where tried */ ! int sp_startcol; /* next match in sp_line_id line */ ! short *sp_cont_list; /* cont. group IDs, if non-zero */ ! short *sp_next_list; /* next group IDs, if non-zero */ ! struct sp_syn sp_syn; /* struct passed to in_id_list() */ ! char_u *sp_pattern; /* regexp to match, pattern */ ! regprog_T *sp_prog; /* regexp to match, program */ #ifdef FEAT_PROFILE syn_time_T sp_time; #endif } synpat_T; ! /* The sp_off_flags are computed like this: ! * offset from the start of the matched text: (1 << SPO_XX_OFF) ! * offset from the end of the matched text: (1 << (SPO_XX_OFF + SPO_COUNT)) ! * When both are present, only one is used. ! */ ! ! #define SPTYPE_MATCH 1 /* match keyword with this group ID */ ! #define SPTYPE_START 2 /* match a regexp, start of item */ ! #define SPTYPE_END 3 /* match a regexp, end of item */ ! #define SPTYPE_SKIP 4 /* match a regexp, skip within item */ #define SYN_ITEMS(buf) ((synpat_T *)((buf)->b_syn_patterns.ga_data)) ! #define NONE_IDX -2 /* value of sp_sync_idx for "NONE" */ /* * Flags for b_syn_sync_flags: */ ! #define SF_CCOMMENT 0x01 /* sync on a C-style comment */ ! #define SF_MATCH 0x02 /* sync by matching a pattern */ #define SYN_STATE_P(ssp) ((bufstate_T *)((ssp)->ga_data)) ! #define MAXKEYWLEN 80 /* maximum length of a keyword */ /* * The attributes of the syntax item that has been recognized. */ ! static int current_attr = 0; /* attr of current syntax word */ #ifdef FEAT_EVAL ! static int current_id = 0; /* ID of current char for syn_get_id() */ ! static int current_trans_id = 0; /* idem, transparency removed */ #endif #ifdef FEAT_CONCEAL static int current_flags = 0; --- 45,105 ---- */ typedef struct syn_pattern { ! char sp_type; // see SPTYPE_ defines below ! char sp_syncing; // this item used for syncing ! short sp_syn_match_id; // highlight group ID of pattern ! short sp_off_flags; // see below ! int sp_offsets[SPO_COUNT]; // offsets ! int sp_flags; // see HL_ defines below #ifdef FEAT_CONCEAL ! int sp_cchar; // conceal substitute character #endif ! int sp_ic; // ignore-case flag for sp_prog ! int sp_sync_idx; // sync item index (syncing only) ! int sp_line_id; // ID of last line where tried ! int sp_startcol; // next match in sp_line_id line ! short *sp_cont_list; // cont. group IDs, if non-zero ! short *sp_next_list; // next group IDs, if non-zero ! struct sp_syn sp_syn; // struct passed to in_id_list() ! char_u *sp_pattern; // regexp to match, pattern ! regprog_T *sp_prog; // regexp to match, program #ifdef FEAT_PROFILE syn_time_T sp_time; #endif } synpat_T; ! // The sp_off_flags are computed like this: ! // offset from the start of the matched text: (1 << SPO_XX_OFF) ! // offset from the end of the matched text: (1 << (SPO_XX_OFF + SPO_COUNT)) ! // When both are present, only one is used. ! ! #define SPTYPE_MATCH 1 // match keyword with this group ID ! #define SPTYPE_START 2 // match a regexp, start of item ! #define SPTYPE_END 3 // match a regexp, end of item ! #define SPTYPE_SKIP 4 // match a regexp, skip within item #define SYN_ITEMS(buf) ((synpat_T *)((buf)->b_syn_patterns.ga_data)) ! #define NONE_IDX -2 // value of sp_sync_idx for "NONE" /* * Flags for b_syn_sync_flags: */ ! #define SF_CCOMMENT 0x01 // sync on a C-style comment ! #define SF_MATCH 0x02 // sync by matching a pattern #define SYN_STATE_P(ssp) ((bufstate_T *)((ssp)->ga_data)) ! #define MAXKEYWLEN 80 // maximum length of a keyword /* * The attributes of the syntax item that has been recognized. */ ! static int current_attr = 0; // attr of current syntax word #ifdef FEAT_EVAL ! static int current_id = 0; // ID of current char for syn_get_id() ! static int current_trans_id = 0; // idem, transparency removed #endif #ifdef FEAT_CONCEAL static int current_flags = 0; *************** *** 110,126 **** typedef struct syn_cluster_S { ! char_u *scl_name; /* syntax cluster name */ ! char_u *scl_name_u; /* uppercase of scl_name */ ! short *scl_list; /* IDs in this syntax cluster */ } syn_cluster_T; /* * Methods of combining two clusters */ ! #define CLUSTER_REPLACE 1 /* replace first list with second */ ! #define CLUSTER_ADD 2 /* add second list to first */ ! #define CLUSTER_SUBTRACT 3 /* subtract second list from first */ #define SYN_CLSTR(buf) ((syn_cluster_T *)((buf)->b_syn_clusters.ga_data)) --- 109,125 ---- typedef struct syn_cluster_S { ! char_u *scl_name; // syntax cluster name ! char_u *scl_name_u; // uppercase of scl_name ! short *scl_list; // IDs in this syntax cluster } syn_cluster_T; /* * Methods of combining two clusters */ ! #define CLUSTER_REPLACE 1 // replace first list with second ! #define CLUSTER_ADD 2 // add second list to first ! #define CLUSTER_SUBTRACT 3 // subtract second list from first #define SYN_CLSTR(buf) ((syn_cluster_T *)((buf)->b_syn_clusters.ga_data)) *************** *** 132,143 **** * 22000 - 22999 CONTAINED indicator (current_syn_inc_tag added) * 23000 - 32767 cluster IDs (subtract SYNID_CLUSTER for the cluster ID) */ ! #define SYNID_ALLBUT MAX_HL_ID /* syntax group ID for contains=ALLBUT */ ! #define SYNID_TOP 21000 /* syntax group ID for contains=TOP */ ! #define SYNID_CONTAINED 22000 /* syntax group ID for contains=CONTAINED */ ! #define SYNID_CLUSTER 23000 /* first syntax group ID for clusters */ ! #define MAX_SYN_INC_TAG 999 /* maximum before the above overflow */ #define MAX_CLUSTER_ID (32767 - SYNID_CLUSTER) /* --- 131,142 ---- * 22000 - 22999 CONTAINED indicator (current_syn_inc_tag added) * 23000 - 32767 cluster IDs (subtract SYNID_CLUSTER for the cluster ID) */ ! #define SYNID_ALLBUT MAX_HL_ID // syntax group ID for contains=ALLBUT ! #define SYNID_TOP 21000 // syntax group ID for contains=TOP ! #define SYNID_CONTAINED 22000 // syntax group ID for contains=CONTAINED ! #define SYNID_CLUSTER 23000 // first syntax group ID for clusters ! #define MAX_SYN_INC_TAG 999 // maximum before the above overflow #define MAX_CLUSTER_ID (32767 - SYNID_CLUSTER) /* *************** *** 183,219 **** */ typedef struct state_item { ! int si_idx; /* index of syntax pattern or ! KEYWORD_IDX */ ! int si_id; /* highlight group ID for keywords */ ! int si_trans_id; /* idem, transparency removed */ ! int si_m_lnum; /* lnum of the match */ ! int si_m_startcol; /* starting column of the match */ ! lpos_T si_m_endpos; /* just after end posn of the match */ ! lpos_T si_h_startpos; /* start position of the highlighting */ ! lpos_T si_h_endpos; /* end position of the highlighting */ ! lpos_T si_eoe_pos; /* end position of end pattern */ ! int si_end_idx; /* group ID for end pattern or zero */ ! int si_ends; /* if match ends before si_m_endpos */ ! int si_attr; /* attributes in this state */ ! long si_flags; /* HL_HAS_EOL flag in this state, and ! * HL_SKIP* for si_next_list */ #ifdef FEAT_CONCEAL ! int si_seqnr; /* sequence number */ ! int si_cchar; /* substitution character for conceal */ #endif ! short *si_cont_list; /* list of contained groups */ ! short *si_next_list; /* nextgroup IDs after this item ends */ ! reg_extmatch_T *si_extmatch; /* \z(...\) matches from start ! * pattern */ } stateitem_T; ! #define KEYWORD_IDX -1 /* value of si_idx for keywords */ ! #define ID_LIST_ALL (short *)-1 /* valid of si_cont_list for containing all ! but contained groups */ #ifdef FEAT_CONCEAL ! static int next_seqnr = 1; /* value to use for si_seqnr */ #endif /* --- 182,218 ---- */ typedef struct state_item { ! int si_idx; // index of syntax pattern or ! // KEYWORD_IDX ! int si_id; // highlight group ID for keywords ! int si_trans_id; // idem, transparency removed ! int si_m_lnum; // lnum of the match ! int si_m_startcol; // starting column of the match ! lpos_T si_m_endpos; // just after end posn of the match ! lpos_T si_h_startpos; // start position of the highlighting ! lpos_T si_h_endpos; // end position of the highlighting ! lpos_T si_eoe_pos; // end position of end pattern ! int si_end_idx; // group ID for end pattern or zero ! int si_ends; // if match ends before si_m_endpos ! int si_attr; // attributes in this state ! long si_flags; // HL_HAS_EOL flag in this state, and ! // HL_SKIP* for si_next_list #ifdef FEAT_CONCEAL ! int si_seqnr; // sequence number ! int si_cchar; // substitution character for conceal #endif ! short *si_cont_list; // list of contained groups ! short *si_next_list; // nextgroup IDs after this item ends ! reg_extmatch_T *si_extmatch; // \z(...\) matches from start ! // pattern } stateitem_T; ! #define KEYWORD_IDX -1 // value of si_idx for keywords ! #define ID_LIST_ALL (short *)-1 // valid of si_cont_list for containing all ! // but contained groups #ifdef FEAT_CONCEAL ! static int next_seqnr = 1; // value to use for si_seqnr #endif /* *************** *** 222,235 **** */ typedef struct { ! int flags; /* flags for contained and transparent */ ! int keyword; /* TRUE for ":syn keyword" */ ! int *sync_idx; /* syntax item for "grouphere" argument, NULL ! if not allowed */ ! char has_cont_list; /* TRUE if "cont_list" can be used */ ! short *cont_list; /* group IDs for "contains" argument */ ! short *cont_in_list; /* group IDs for "containedin" argument */ ! short *next_list; /* group IDs for "nextgroup" argument */ } syn_opt_arg_T; /* --- 221,234 ---- */ typedef struct { ! int flags; // flags for contained and transparent ! int keyword; // TRUE for ":syn keyword" ! int *sync_idx; // syntax item for "grouphere" argument, NULL ! // if not allowed ! char has_cont_list; // TRUE if "cont_list" can be used ! short *cont_list; // group IDs for "contains" argument ! short *cont_in_list; // group IDs for "containedin" argument ! short *next_list; // group IDs for "nextgroup" argument } syn_opt_arg_T; /* *************** *** 239,253 **** * If next_match_col == MAXCOL, no match found in this line. * (All end positions have the column of the char after the end) */ ! static int next_match_col; /* column for start of next match */ ! static lpos_T next_match_m_endpos; /* position for end of next match */ ! static lpos_T next_match_h_startpos; /* pos. for highl. start of next match */ ! static lpos_T next_match_h_endpos; /* pos. for highl. end of next match */ ! static int next_match_idx; /* index of matched item */ ! static long next_match_flags; /* flags for next match */ ! static lpos_T next_match_eos_pos; /* end of start pattn (start region) */ ! static lpos_T next_match_eoe_pos; /* pos. for end of end pattern */ ! static int next_match_end_idx; /* ID of group for end pattn or zero */ static reg_extmatch_T *next_match_extmatch = NULL; /* --- 238,252 ---- * If next_match_col == MAXCOL, no match found in this line. * (All end positions have the column of the char after the end) */ ! static int next_match_col; // column for start of next match ! static lpos_T next_match_m_endpos; // position for end of next match ! static lpos_T next_match_h_startpos; // pos. for highl. start of next match ! static lpos_T next_match_h_endpos; // pos. for highl. end of next match ! static int next_match_idx; // index of matched item ! static long next_match_flags; // flags for next match ! static lpos_T next_match_eos_pos; // end of start pattn (start region) ! static lpos_T next_match_eoe_pos; // pos. for end of end pattern ! static int next_match_end_idx; // ID of group for end pattn or zero static reg_extmatch_T *next_match_extmatch = NULL; /* *************** *** 261,282 **** * The current state (within the line) of the recognition engine. * When current_state.ga_itemsize is 0 the current state is invalid. */ ! static win_T *syn_win; /* current window for highlighting */ ! static buf_T *syn_buf; /* current buffer for highlighting */ ! static synblock_T *syn_block; /* current buffer for highlighting */ #ifdef FEAT_RELTIME ! static proftime_T *syn_tm; /* timeout limit */ #endif ! static linenr_T current_lnum = 0; /* lnum of current state */ ! static colnr_T current_col = 0; /* column of current state */ ! static int current_state_stored = 0; /* TRUE if stored current state ! * after setting current_finished */ ! static int current_finished = 0; /* current line has been finished */ ! static garray_T current_state /* current stack of state_items */ = {0, 0, 0, 0, NULL}; ! static short *current_next_list = NULL; /* when non-zero, nextgroup list */ ! static int current_next_flags = 0; /* flags for current_next_list */ ! static int current_line_id = 0; /* unique number for current line */ #define CUR_STATE(idx) ((stateitem_T *)(current_state.ga_data))[idx] --- 260,281 ---- * The current state (within the line) of the recognition engine. * When current_state.ga_itemsize is 0 the current state is invalid. */ ! static win_T *syn_win; // current window for highlighting ! static buf_T *syn_buf; // current buffer for highlighting ! static synblock_T *syn_block; // current buffer for highlighting #ifdef FEAT_RELTIME ! static proftime_T *syn_tm; // timeout limit #endif ! static linenr_T current_lnum = 0; // lnum of current state ! static colnr_T current_col = 0; // column of current state ! static int current_state_stored = 0; // TRUE if stored current state ! // after setting current_finished ! static int current_finished = 0; // current line has been finished ! static garray_T current_state // current stack of state_items = {0, 0, 0, 0, NULL}; ! static short *current_next_list = NULL; // when non-zero, nextgroup list ! static int current_next_flags = 0; // flags for current_next_list ! static int current_line_id = 0; // unique number for current line #define CUR_STATE(idx) ((stateitem_T *)(current_state.ga_data))[idx] *************** *** 377,383 **** linenr_T parsed_lnum; linenr_T first_stored; int dist; ! static varnumber_T changedtick = 0; /* remember the last change ID */ #ifdef FEAT_CONCEAL current_sub_char = NUL; --- 376,382 ---- linenr_T parsed_lnum; linenr_T first_stored; int dist; ! static varnumber_T changedtick = 0; // remember the last change ID #ifdef FEAT_CONCEAL current_sub_char = NUL; *************** *** 404,410 **** */ syn_stack_alloc(); if (syn_block->b_sst_array == NULL) ! return; /* out of memory */ syn_block->b_sst_lasttick = display_tick; /* --- 403,409 ---- */ syn_stack_alloc(); if (syn_block->b_sst_array == NULL) ! return; // out of memory syn_block->b_sst_lasttick = display_tick; /* *************** *** 438,444 **** */ if (INVALID_STATE(¤t_state) && syn_block->b_sst_array != NULL) { ! /* Find last valid saved state before start_lnum. */ for (p = syn_block->b_sst_first; p != NULL; p = p->sst_next) { if (p->sst_lnum > lnum) --- 437,443 ---- */ if (INVALID_STATE(¤t_state) && syn_block->b_sst_array != NULL) { ! // Find last valid saved state before start_lnum. for (p = syn_block->b_sst_first; p != NULL; p = p->sst_next) { if (p->sst_lnum > lnum) *************** *** 462,472 **** { syn_sync(wp, lnum, last_valid); if (current_lnum == 1) ! /* First line is always valid, no matter "minlines". */ first_stored = 1; else ! /* Need to parse "minlines" lines before state can be considered ! * valid to store. */ first_stored = current_lnum + syn_block->b_syn_sync_minlines; } else --- 461,471 ---- { syn_sync(wp, lnum, last_valid); if (current_lnum == 1) ! // First line is always valid, no matter "minlines". first_stored = 1; else ! // Need to parse "minlines" lines before state can be considered ! // valid to store. first_stored = current_lnum + syn_block->b_syn_sync_minlines; } else *************** *** 486,498 **** (void)syn_finish_line(FALSE); ++current_lnum; ! /* If we parsed at least "minlines" lines or started at a valid ! * state, the current state is considered valid. */ if (current_lnum >= first_stored) { ! /* Check if the saved state entry is for the current line and is ! * equal to the current state. If so, then validate all saved ! * states that depended on a change before the parsed line. */ if (prev == NULL) prev = syn_stack_find_entry(current_lnum - 1); if (prev == NULL) --- 485,497 ---- (void)syn_finish_line(FALSE); ++current_lnum; ! // If we parsed at least "minlines" lines or started at a valid ! // state, the current state is considered valid. if (current_lnum >= first_stored) { ! // Check if the saved state entry is for the current line and is ! // equal to the current state. If so, then validate all saved ! // states that depended on a change before the parsed line. if (prev == NULL) prev = syn_stack_find_entry(current_lnum - 1); if (prev == NULL) *************** *** 510,536 **** while (sp != NULL && sp->sst_change_lnum <= parsed_lnum) { if (sp->sst_lnum <= lnum) ! /* valid state before desired line, use this one */ prev = sp; else if (sp->sst_change_lnum == 0) ! /* past saved states depending on change, break here. */ break; sp->sst_change_lnum = 0; sp = sp->sst_next; } load_current_state(prev); } ! /* Store the state at this line when it's the first one, the line ! * where we start parsing, or some distance from the previously ! * saved state. But only when parsed at least 'minlines'. */ else if (prev == NULL || current_lnum == lnum || current_lnum >= prev->sst_lnum + dist) prev = store_current_state(); } ! /* This can take a long time: break when CTRL-C pressed. The current ! * state will be wrong then. */ line_breakcheck(); if (got_int) { --- 509,535 ---- while (sp != NULL && sp->sst_change_lnum <= parsed_lnum) { if (sp->sst_lnum <= lnum) ! // valid state before desired line, use this one prev = sp; else if (sp->sst_change_lnum == 0) ! // past saved states depending on change, break here. break; sp->sst_change_lnum = 0; sp = sp->sst_next; } load_current_state(prev); } ! // Store the state at this line when it's the first one, the line ! // where we start parsing, or some distance from the previously ! // saved state. But only when parsed at least 'minlines'. else if (prev == NULL || current_lnum == lnum || current_lnum >= prev->sst_lnum + dist) prev = store_current_state(); } ! // This can take a long time: break when CTRL-C pressed. The current ! // state will be wrong then. line_breakcheck(); if (got_int) { *************** *** 652,659 **** */ if (syn_block->b_syn_sync_flags & SF_CCOMMENT) { ! /* Need to make syn_buf the current buffer for a moment, to be able to ! * use find_start_comment(). */ curwin_save = curwin; curwin = wp; curbuf_save = curbuf; --- 651,658 ---- */ if (syn_block->b_syn_sync_flags & SF_CCOMMENT) { ! // Need to make syn_buf the current buffer for a moment, to be able to ! // use find_start_comment(). curwin_save = curwin; curwin = wp; curbuf_save = curbuf; *************** *** 670,676 **** } current_lnum = start_lnum; ! /* set cursor to start of search */ cursor_save = wp->w_cursor; wp->w_cursor.lnum = start_lnum; wp->w_cursor.col = 0; --- 669,675 ---- } current_lnum = start_lnum; ! // set cursor to start of search cursor_save = wp->w_cursor; wp->w_cursor.lnum = start_lnum; wp->w_cursor.col = 0; *************** *** 694,700 **** } } ! /* restore cursor and buffer */ wp->w_cursor = cursor_save; curwin = curwin_save; curbuf = curbuf_save; --- 693,699 ---- } } ! // restore cursor and buffer wp->w_cursor = cursor_save; curwin = curwin_save; curbuf = curbuf_save; *************** *** 717,723 **** lnum = start_lnum; while (--lnum > break_lnum) { ! /* This can take a long time: break when CTRL-C pressed. */ line_breakcheck(); if (got_int) { --- 716,722 ---- lnum = start_lnum; while (--lnum > break_lnum) { ! // This can take a long time: break when CTRL-C pressed. line_breakcheck(); if (got_int) { *************** *** 726,732 **** break; } ! /* Check if we have run into a valid saved state stack now. */ if (last_valid != NULL && lnum == last_valid->sst_lnum) { load_current_state(last_valid); --- 725,731 ---- break; } ! // Check if we have run into a valid saved state stack now. if (last_valid != NULL && lnum == last_valid->sst_lnum) { load_current_state(last_valid); *************** *** 759,771 **** cur_si = &CUR_STATE(current_state.ga_len - 1); if (cur_si->si_m_endpos.lnum > start_lnum) { ! /* ignore match that goes to after where started */ current_lnum = end_lnum; break; } if (cur_si->si_idx < 0) { ! /* Cannot happen? */ found_flags = 0; found_match_idx = KEYWORD_IDX; } --- 758,770 ---- cur_si = &CUR_STATE(current_state.ga_len - 1); if (cur_si->si_m_endpos.lnum > start_lnum) { ! // ignore match that goes to after where started current_lnum = end_lnum; break; } if (cur_si->si_idx < 0) { ! // Cannot happen? found_flags = 0; found_match_idx = KEYWORD_IDX; } *************** *** 794,802 **** else ++current_col; ! /* syn_current_attr() will have skipped the check for ! * an item that ends here, need to do that now. Be ! * careful not to go past the NUL. */ prev_current_col = current_col; if (syn_getcurline()[current_col] != NUL) ++current_col; --- 793,801 ---- else ++current_col; ! // syn_current_attr() will have skipped the check for ! // an item that ends here, need to do that now. Be ! // careful not to go past the NUL. prev_current_col = current_col; if (syn_getcurline()[current_col] != NUL) ++current_col; *************** *** 854,860 **** invalidate_current_state(); } ! /* Ran into start of the file or exceeded maximum number of lines */ if (lnum <= break_lnum) { invalidate_current_state(); --- 853,859 ---- invalidate_current_state(); } ! // Ran into start of the file or exceeded maximum number of lines if (lnum <= break_lnum) { invalidate_current_state(); *************** *** 891,901 **** { regmmatch_T regmatch; int r; ! char_u buf_chartab[32]; /* chartab array for syn iskyeyword */ if (syn_block->b_syn_linecont_prog != NULL) { ! /* use syntax iskeyword option */ save_chartab(buf_chartab); regmatch.rmm_ic = syn_block->b_syn_linecont_ic; regmatch.regprog = syn_block->b_syn_linecont_prog; --- 890,900 ---- { regmmatch_T regmatch; int r; ! char_u buf_chartab[32]; // chartab array for syn iskyeyword if (syn_block->b_syn_linecont_prog != NULL) { ! // use syntax iskeyword option save_chartab(buf_chartab); regmatch.rmm_ic = syn_block->b_syn_linecont_ic; regmatch.regprog = syn_block->b_syn_linecont_prog; *************** *** 948,955 **** if (startofline) { ! /* Check for a match carried over from a previous line with a ! * contained region. The match ends as soon as the region ends. */ for (i = 0; i < current_state.ga_len; ++i) { cur_si = &CUR_STATE(i); --- 947,954 ---- if (startofline) { ! // Check for a match carried over from a previous line with a ! // contained region. The match ends as soon as the region ends. for (i = 0; i < current_state.ga_len; ++i) { cur_si = &CUR_STATE(i); *************** *** 990,996 **** || (seen_keepend && !startofline) || (i == current_state.ga_len - 1 && startofline)) { ! cur_si->si_h_startpos.col = 0; /* start highl. in col 0 */ cur_si->si_h_startpos.lnum = current_lnum; if (!(cur_si->si_flags & HL_MATCHCONT)) --- 989,995 ---- || (seen_keepend && !startofline) || (i == current_state.ga_len - 1 && startofline)) { ! cur_si->si_h_startpos.col = 0; // start highl. in col 0 cur_si->si_h_startpos.lnum = current_lnum; if (!(cur_si->si_flags & HL_MATCHCONT)) *************** *** 1003,1011 **** check_keepend(); } ! /**************************************** ! * Handling of the state stack cache. ! */ /* * EXPLANATION OF THE SYNTAX STATE STACK CACHE --- 1002,1009 ---- check_keepend(); } ! ///////////////////////////////////////// ! // Handling of the state stack cache. /* * EXPLANATION OF THE SYNTAX STATE STACK CACHE *************** *** 1067,1073 **** syn_stack_free_block(block); #ifdef FEAT_FOLDING ! /* When using "syntax" fold method, must update all folds. */ FOR_ALL_WINDOWS(wp) { if (wp->w_s == block && foldmethodIsSyntax(wp)) --- 1065,1071 ---- syn_stack_free_block(block); #ifdef FEAT_FOLDING ! // When using "syntax" fold method, must update all folds. FOR_ALL_WINDOWS(wp) { if (wp->w_s == block && foldmethodIsSyntax(wp)) *************** *** 1096,1102 **** len = SST_MAX_ENTRIES; if (syn_block->b_sst_len > len * 2 || syn_block->b_sst_len < len) { ! /* Allocate 50% too much, to avoid reallocating too often. */ len = syn_buf->b_ml.ml_line_count; len = (len + len / 2) / SST_DIST + Rows * 2; if (len < SST_MIN_ENTRIES) --- 1094,1100 ---- len = SST_MAX_ENTRIES; if (syn_block->b_sst_len > len * 2 || syn_block->b_sst_len < len) { ! // Allocate 50% too much, to avoid reallocating too often. len = syn_buf->b_ml.ml_line_count; len = (len + len / 2) / SST_DIST + Rows * 2; if (len < SST_MIN_ENTRIES) *************** *** 1106,1113 **** if (syn_block->b_sst_array != NULL) { ! /* When shrinking the array, cleanup the existing stack. ! * Make sure that all valid entries fit in the new array. */ while (syn_block->b_sst_len - syn_block->b_sst_freecount + 2 > len && syn_stack_cleanup()) ; --- 1104,1111 ---- if (syn_block->b_sst_array != NULL) { ! // When shrinking the array, cleanup the existing stack. ! // Make sure that all valid entries fit in the new array. while (syn_block->b_sst_len - syn_block->b_sst_freecount + 2 > len && syn_stack_cleanup()) ; *************** *** 1116,1128 **** } sstp = ALLOC_CLEAR_MULT(synstate_T, len); ! if (sstp == NULL) /* out of memory! */ return; to = sstp - 1; if (syn_block->b_sst_array != NULL) { ! /* Move the states from the old array to the new one. */ for (from = syn_block->b_sst_first; from != NULL; from = from->sst_next) { --- 1114,1126 ---- } sstp = ALLOC_CLEAR_MULT(synstate_T, len); ! if (sstp == NULL) // out of memory! return; to = sstp - 1; if (syn_block->b_sst_array != NULL) { ! // Move the states from the old array to the new one. for (from = syn_block->b_sst_first; from != NULL; from = from->sst_next) { *************** *** 1143,1149 **** syn_block->b_sst_freecount = len; } ! /* Create the list of free entries. */ syn_block->b_sst_firstfree = to + 1; while (++to < sstp + len) to->sst_next = to + 1; --- 1141,1147 ---- syn_block->b_sst_freecount = len; } ! // Create the list of free entries. syn_block->b_sst_firstfree = to + 1; while (++to < sstp + len) to->sst_next = to + 1; *************** *** 1189,1195 **** n = p->sst_lnum + buf->b_mod_xlines; if (n <= buf->b_mod_bot) { ! /* this state is inside the changed area, remove it */ np = p->sst_next; if (prev == NULL) block->b_sst_first = np; --- 1187,1193 ---- n = p->sst_lnum + buf->b_mod_xlines; if (n <= buf->b_mod_bot) { ! // this state is inside the changed area, remove it np = p->sst_next; if (prev == NULL) block->b_sst_first = np; *************** *** 1199,1207 **** p = np; continue; } ! /* This state is below the changed area. Remember the line ! * that needs to be parsed before this entry can be made valid ! * again. */ if (p->sst_change_lnum != 0 && p->sst_change_lnum > buf->b_mod_top) { if (p->sst_change_lnum + buf->b_mod_xlines > buf->b_mod_top) --- 1197,1205 ---- p = np; continue; } ! // This state is below the changed area. Remember the line ! // that needs to be parsed before this entry can be made valid ! // again. if (p->sst_change_lnum != 0 && p->sst_change_lnum > buf->b_mod_top) { if (p->sst_change_lnum + buf->b_mod_xlines > buf->b_mod_top) *************** *** 1236,1242 **** if (syn_block->b_sst_first == NULL) return retval; ! /* Compute normal distance between non-displayed entries. */ if (syn_block->b_sst_len <= Rows) dist = 999999; else --- 1234,1240 ---- if (syn_block->b_sst_first == NULL) return retval; ! // Compute normal distance between non-displayed entries. if (syn_block->b_sst_len <= Rows) dist = 999999; else *************** *** 1274,1280 **** { if (p->sst_tick == tick && prev->sst_lnum + dist > p->sst_lnum) { ! /* Move this entry from used list to free list */ prev->sst_next = p->sst_next; syn_stack_free_entry(syn_block, p); p = prev; --- 1272,1278 ---- { if (p->sst_tick == tick && prev->sst_lnum + dist > p->sst_lnum) { ! // Move this entry from used list to free list prev->sst_next = p->sst_next; syn_stack_free_entry(syn_block, p); p = prev; *************** *** 1348,1364 **** { if (sp != NULL) { ! /* find "sp" in the list and remove it */ if (syn_block->b_sst_first == sp) ! /* it's the first entry */ syn_block->b_sst_first = sp->sst_next; else { ! /* find the entry just before this one to adjust sst_next */ for (p = syn_block->b_sst_first; p != NULL; p = p->sst_next) if (p->sst_next == sp) break; ! if (p != NULL) /* just in case */ p->sst_next = sp->sst_next; } syn_stack_free_entry(syn_block, sp); --- 1346,1362 ---- { if (sp != NULL) { ! // find "sp" in the list and remove it if (syn_block->b_sst_first == sp) ! // it's the first entry syn_block->b_sst_first = sp->sst_next; else { ! // find the entry just before this one to adjust sst_next for (p = syn_block->b_sst_first; p != NULL; p = p->sst_next) if (p->sst_next == sp) break; ! if (p != NULL) // just in case p->sst_next = sp->sst_next; } syn_stack_free_entry(syn_block, sp); *************** *** 1370,1401 **** /* * Add a new entry */ ! /* If no free items, cleanup the array first. */ if (syn_block->b_sst_freecount == 0) { (void)syn_stack_cleanup(); ! /* "sp" may have been moved to the freelist now */ sp = syn_stack_find_entry(current_lnum); } ! /* Still no free items? Must be a strange problem... */ if (syn_block->b_sst_freecount == 0) sp = NULL; else { ! /* Take the first item from the free list and put it in the used ! * list, after *sp */ p = syn_block->b_sst_firstfree; syn_block->b_sst_firstfree = p->sst_next; --syn_block->b_sst_freecount; if (sp == NULL) { ! /* Insert in front of the list */ p->sst_next = syn_block->b_sst_first; syn_block->b_sst_first = p; } else { ! /* insert in list after *sp */ p->sst_next = sp->sst_next; sp->sst_next = p; } --- 1368,1399 ---- /* * Add a new entry */ ! // If no free items, cleanup the array first. if (syn_block->b_sst_freecount == 0) { (void)syn_stack_cleanup(); ! // "sp" may have been moved to the freelist now sp = syn_stack_find_entry(current_lnum); } ! // Still no free items? Must be a strange problem... if (syn_block->b_sst_freecount == 0) sp = NULL; else { ! // Take the first item from the free list and put it in the used ! // list, after *sp p = syn_block->b_sst_firstfree; syn_block->b_sst_firstfree = p->sst_next; --syn_block->b_sst_freecount; if (sp == NULL) { ! // Insert in front of the list p->sst_next = syn_block->b_sst_first; syn_block->b_sst_first = p; } else { ! // insert in list after *sp p->sst_next = sp->sst_next; sp->sst_next = p; } *************** *** 1406,1418 **** } if (sp != NULL) { ! /* When overwriting an existing state stack, clear it first */ clear_syn_state(sp); sp->sst_stacksize = current_state.ga_len; if (current_state.ga_len > SST_FIX_STATES) { ! /* Need to clear it, might be something remaining from when the ! * length was less than SST_FIX_STATES. */ ga_init2(&sp->sst_union.sst_ga, (int)sizeof(bufstate_T), 1); if (ga_grow(&sp->sst_union.sst_ga, current_state.ga_len) == FAIL) sp->sst_stacksize = 0; --- 1404,1416 ---- } if (sp != NULL) { ! // When overwriting an existing state stack, clear it first clear_syn_state(sp); sp->sst_stacksize = current_state.ga_len; if (current_state.ga_len > SST_FIX_STATES) { ! // Need to clear it, might be something remaining from when the ! // length was less than SST_FIX_STATES. ga_init2(&sp->sst_union.sst_ga, (int)sizeof(bufstate_T), 1); if (ga_grow(&sp->sst_union.sst_ga, current_state.ga_len) == FAIL) sp->sst_stacksize = 0; *************** *** 1498,1508 **** bufstate_T *bp; reg_extmatch_T *six, *bsx; ! /* First a quick check if the stacks have the same size end nextlist. */ if (sp->sst_stacksize == current_state.ga_len && sp->sst_next_list == current_next_list) { ! /* Need to compare all states on both stacks. */ if (sp->sst_stacksize > SST_FIX_STATES) bp = SYN_STATE_P(&(sp->sst_union.sst_ga)); else --- 1496,1506 ---- bufstate_T *bp; reg_extmatch_T *six, *bsx; ! // First a quick check if the stacks have the same size end nextlist. if (sp->sst_stacksize == current_state.ga_len && sp->sst_next_list == current_next_list) { ! // Need to compare all states on both stacks. if (sp->sst_stacksize > SST_FIX_STATES) bp = SYN_STATE_P(&(sp->sst_union.sst_ga)); else *************** *** 1510,1538 **** for (i = current_state.ga_len; --i >= 0; ) { ! /* If the item has another index the state is different. */ if (bp[i].bs_idx != CUR_STATE(i).si_idx) break; if (bp[i].bs_extmatch != CUR_STATE(i).si_extmatch) { ! /* When the extmatch pointers are different, the strings in ! * them can still be the same. Check if the extmatch ! * references are equal. */ bsx = bp[i].bs_extmatch; six = CUR_STATE(i).si_extmatch; ! /* If one of the extmatch pointers is NULL the states are ! * different. */ if (bsx == NULL || six == NULL) break; for (j = 0; j < NSUBEXP; ++j) { ! /* Check each referenced match string. They must all be ! * equal. */ if (bsx->matches[j] != six->matches[j]) { ! /* If the pointer is different it can still be the ! * same text. Compare the strings, ignore case when ! * the start item has the sp_ic flag set. */ if (bsx->matches[j] == NULL || six->matches[j] == NULL) break; --- 1508,1536 ---- for (i = current_state.ga_len; --i >= 0; ) { ! // If the item has another index the state is different. if (bp[i].bs_idx != CUR_STATE(i).si_idx) break; if (bp[i].bs_extmatch != CUR_STATE(i).si_extmatch) { ! // When the extmatch pointers are different, the strings in ! // them can still be the same. Check if the extmatch ! // references are equal. bsx = bp[i].bs_extmatch; six = CUR_STATE(i).si_extmatch; ! // If one of the extmatch pointers is NULL the states are ! // different. if (bsx == NULL || six == NULL) break; for (j = 0; j < NSUBEXP; ++j) { ! // Check each referenced match string. They must all be ! // equal. if (bsx->matches[j] != six->matches[j]) { ! // If the pointer is different it can still be the ! // same text. Compare the strings, ignore case when ! // the start item has the sp_ic flag set. if (bsx->matches[j] == NULL || six->matches[j] == NULL) break; *************** *** 1584,1590 **** invalidate_current_state(void) { clear_current_state(); ! current_state.ga_itemsize = 0; /* mark current_state invalid */ current_next_list = NULL; keepend_level = -1; } --- 1582,1588 ---- invalidate_current_state(void) { clear_current_state(); ! current_state.ga_itemsize = 0; // mark current_state invalid current_next_list = NULL; keepend_level = -1; } *************** *** 1651,1657 **** */ static int syn_finish_line( ! int syncing) /* called for syncing */ { stateitem_T *cur_si; colnr_T prev_current_col; --- 1649,1655 ---- */ static int syn_finish_line( ! int syncing) // called for syncing { stateitem_T *cur_si; colnr_T prev_current_col; *************** *** 1673,1681 **** & (HL_SYNC_HERE|HL_SYNC_THERE))) return TRUE; ! /* syn_current_attr() will have skipped the check for an item ! * that ends here, need to do that now. Be careful not to go ! * past the NUL. */ prev_current_col = current_col; if (syn_getcurline()[current_col] != NUL) ++current_col; --- 1671,1679 ---- & (HL_SYNC_HERE|HL_SYNC_THERE))) return TRUE; ! // syn_current_attr() will have skipped the check for an item ! // that ends here, need to do that now. Be careful not to go ! // past the NUL. prev_current_col = current_col; if (syn_getcurline()[current_col] != NUL) ++current_col; *************** *** 1700,1721 **** get_syntax_attr( colnr_T col, int *can_spell, ! int keep_state) /* keep state of char at "col" */ { int attr = 0; if (can_spell != NULL) ! /* Default: Only do spelling when there is no @Spell cluster or when ! * ":syn spell toplevel" was used. */ *can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT ? (syn_block->b_spell_cluster_id == 0) : (syn_block->b_syn_spell == SYNSPL_TOP); ! /* check for out of memory situation */ if (syn_block->b_sst_array == NULL) return 0; ! /* After 'synmaxcol' the attribute is always zero. */ if (syn_buf->b_p_smc > 0 && col >= (colnr_T)syn_buf->b_p_smc) { clear_current_state(); --- 1698,1719 ---- get_syntax_attr( colnr_T col, int *can_spell, ! int keep_state) // keep state of char at "col" { int attr = 0; if (can_spell != NULL) ! // Default: Only do spelling when there is no @Spell cluster or when ! // ":syn spell toplevel" was used. *can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT ? (syn_block->b_spell_cluster_id == 0) : (syn_block->b_syn_spell == SYNSPL_TOP); ! // check for out of memory situation if (syn_block->b_sst_array == NULL) return 0; ! // After 'synmaxcol' the attribute is always zero. if (syn_buf->b_p_smc > 0 && col >= (colnr_T)syn_buf->b_p_smc) { clear_current_state(); *************** *** 1730,1736 **** return 0; } ! /* Make sure current_state is valid */ if (INVALID_STATE(¤t_state)) validate_current_state(); --- 1728,1734 ---- return 0; } ! // Make sure current_state is valid if (INVALID_STATE(¤t_state)) validate_current_state(); *************** *** 1752,1769 **** */ static int syn_current_attr( ! int syncing, /* When 1: called for syncing */ ! int displaying, /* result will be displayed */ ! int *can_spell, /* return: do spell checking */ ! int keep_state) /* keep syntax stack afterwards */ { int syn_id; ! lpos_T endpos; /* was: char_u *endp; */ ! lpos_T hl_startpos; /* was: int hl_startcol; */ lpos_T hl_endpos; ! lpos_T eos_pos; /* end-of-start match (start region) */ ! lpos_T eoe_pos; /* end-of-end pattern */ ! int end_idx; /* group ID for end pattern */ int idx; synpat_T *spp; stateitem_T *cur_si, *sip = NULL; --- 1750,1767 ---- */ static int syn_current_attr( ! int syncing, // When 1: called for syncing ! int displaying, // result will be displayed ! int *can_spell, // return: do spell checking ! int keep_state) // keep syntax stack afterwards { int syn_id; ! lpos_T endpos; // was: char_u *endp; ! lpos_T hl_startpos; // was: int hl_startcol; lpos_T hl_endpos; ! lpos_T eos_pos; // end-of-start match (start region) ! lpos_T eoe_pos; // end-of-end pattern ! int end_idx; // group ID for end pattern int idx; synpat_T *spp; stateitem_T *cur_si, *sip = NULL; *************** *** 1772,1789 **** long flags; int cchar; short *next_list; ! int found_match; /* found usable match */ ! static int try_next_column = FALSE; /* must try in next col */ int do_keywords; regmmatch_T regmatch; lpos_T pos; int lc_col; reg_extmatch_T *cur_extmatch = NULL; ! char_u buf_chartab[32]; /* chartab array for syn iskyeyword */ ! char_u *line; /* current line. NOTE: becomes invalid after ! looking for a pattern match! */ ! /* variables for zero-width matches that have a "nextgroup" argument */ int keep_next_list; int zero_width_next_list = FALSE; garray_T zero_width_next_ga; --- 1770,1787 ---- long flags; int cchar; short *next_list; ! int found_match; // found usable match ! static int try_next_column = FALSE; // must try in next col int do_keywords; regmmatch_T regmatch; lpos_T pos; int lc_col; reg_extmatch_T *cur_extmatch = NULL; ! char_u buf_chartab[32]; // chartab array for syn iskyeyword ! char_u *line; // current line. NOTE: becomes invalid after ! // looking for a pattern match! ! // variables for zero-width matches that have a "nextgroup" argument int keep_next_list; int zero_width_next_list = FALSE; garray_T zero_width_next_ga; *************** *** 1807,1813 **** return 0; } ! /* if the current or next character is NUL, we will finish the line now */ if (line[current_col] == NUL || line[current_col + 1] == NUL) { current_finished = TRUE; --- 1805,1811 ---- return 0; } ! // if the current or next character is NUL, we will finish the line now if (line[current_col] == NUL || line[current_col + 1] == NUL) { current_finished = TRUE; *************** *** 1825,1840 **** try_next_column = FALSE; } ! /* Only check for keywords when not syncing and there are some. */ do_keywords = !syncing && (syn_block->b_keywtab.ht_used > 0 || syn_block->b_keywtab_ic.ht_used > 0); ! /* Init the list of zero-width matches with a nextlist. This is used to ! * avoid matching the same item in the same position twice. */ ga_init2(&zero_width_next_ga, (int)sizeof(int), 10); ! /* use syntax iskeyword option */ save_chartab(buf_chartab); /* --- 1823,1838 ---- try_next_column = FALSE; } ! // Only check for keywords when not syncing and there are some. do_keywords = !syncing && (syn_block->b_keywtab.ht_used > 0 || syn_block->b_keywtab_ic.ht_used > 0); ! // Init the list of zero-width matches with a nextlist. This is used to ! // avoid matching the same item in the same position twice. ga_init2(&zero_width_next_ga, (int)sizeof(int), 10); ! // use syntax iskeyword option save_chartab(buf_chartab); /* *************** *** 1888,1894 **** cur_si = &CUR_STATE(current_state.ga_len - 1); cur_si->si_m_startcol = current_col; cur_si->si_h_startpos.lnum = current_lnum; ! cur_si->si_h_startpos.col = 0; /* starts right away */ cur_si->si_m_endpos.lnum = current_lnum; cur_si->si_m_endpos.col = endcol; cur_si->si_h_endpos.lnum = current_lnum; --- 1886,1892 ---- cur_si = &CUR_STATE(current_state.ga_len - 1); cur_si->si_m_startcol = current_col; cur_si->si_h_startpos.lnum = current_lnum; ! cur_si->si_h_startpos.col = 0; // starts right away cur_si->si_m_endpos.lnum = current_lnum; cur_si->si_m_endpos.col = endcol; cur_si->si_h_endpos.lnum = current_lnum; *************** *** 1950,1956 **** * pattern takes quite a bit of time, thus we want to * avoid doing it when it's not needed. */ ! next_match_idx = 0; /* no match in this line yet */ next_match_col = MAXCOL; for (idx = syn_block->b_syn_patterns.ga_len; --idx >= 0; ) { --- 1948,1954 ---- * pattern takes quite a bit of time, thus we want to * avoid doing it when it's not needed. */ ! next_match_idx = 0; // no match in this line yet next_match_col = MAXCOL; for (idx = syn_block->b_syn_patterns.ga_len; --idx >= 0; ) { *************** *** 1970,1978 **** { int r; ! /* If we already tried matching in this line, and ! * there isn't a match before next_match_col, skip ! * this item. */ if (spp->sp_line_id == current_line_id && spp->sp_startcol >= next_match_col) continue; --- 1968,1976 ---- { int r; ! // If we already tried matching in this line, and ! // there isn't a match before next_match_col, skip ! // this item. if (spp->sp_line_id == current_line_id && spp->sp_startcol >= next_match_col) continue; *************** *** 1991,1997 **** spp->sp_prog = regmatch.regprog; if (!r) { ! /* no match in this line, try another one */ spp->sp_startcol = MAXCOL; continue; } --- 1989,1995 ---- spp->sp_prog = regmatch.regprog; if (!r) { ! // no match in this line, try another one spp->sp_startcol = MAXCOL; continue; } *************** *** 2003,2017 **** spp, SPO_MS_OFF, -1); if (pos.lnum > current_lnum) { ! /* must have used end of match in a next line, ! * we can't handle that */ spp->sp_startcol = MAXCOL; continue; } startcol = pos.col; ! /* remember the next column where this pattern ! * matches in the current line */ spp->sp_startcol = startcol; /* --- 2001,2015 ---- spp, SPO_MS_OFF, -1); if (pos.lnum > current_lnum) { ! // must have used end of match in a next line, ! // we can't handle that spp->sp_startcol = MAXCOL; continue; } startcol = pos.col; ! // remember the next column where this pattern ! // matches in the current line spp->sp_startcol = startcol; /* *************** *** 2035,2046 **** endpos.lnum = regmatch.endpos[0].lnum; endpos.col = regmatch.endpos[0].col; ! /* Compute the highlight start. */ syn_add_start_off(&hl_startpos, ®match, spp, SPO_HS_OFF, -1); ! /* Compute the region start. */ ! /* Default is to use the end of the match. */ syn_add_end_off(&eos_pos, ®match, spp, SPO_RS_OFF, 0); --- 2033,2044 ---- endpos.lnum = regmatch.endpos[0].lnum; endpos.col = regmatch.endpos[0].col; ! // Compute the highlight start. syn_add_start_off(&hl_startpos, ®match, spp, SPO_HS_OFF, -1); ! // Compute the region start. ! // Default is to use the end of the match. syn_add_end_off(&eos_pos, ®match, spp, SPO_RS_OFF, 0); *************** *** 2053,2059 **** re_extmatch_out = NULL; flags = 0; ! eoe_pos.lnum = 0; /* avoid warning */ eoe_pos.col = 0; end_idx = 0; hl_endpos.lnum = 0; --- 2051,2057 ---- re_extmatch_out = NULL; flags = 0; ! eoe_pos.lnum = 0; // avoid warning eoe_pos.col = 0; end_idx = 0; hl_endpos.lnum = 0; *************** *** 2073,2079 **** find_endpos(idx, &startpos, &endpos, &hl_endpos, &flags, &eoe_pos, &end_idx, cur_extmatch); if (endpos.lnum == 0) ! continue; /* not found */ } /* --- 2071,2077 ---- find_endpos(idx, &startpos, &endpos, &hl_endpos, &flags, &eoe_pos, &end_idx, cur_extmatch); if (endpos.lnum == 0) ! continue; // not found } /* *************** *** 2104,2111 **** /* * keep the best match so far in next_match_* */ ! /* Highlighting must start after startpos and end ! * before endpos. */ if (hl_startpos.lnum == current_lnum && (int)hl_startpos.col < startcol) hl_startpos.col = startcol; --- 2102,2109 ---- /* * keep the best match so far in next_match_* */ ! // Highlighting must start after startpos and end ! // before endpos. if (hl_startpos.lnum == current_lnum && (int)hl_startpos.col < startcol) hl_startpos.col = startcol; *************** *** 2134,2141 **** { synpat_T *lspp; ! /* When a zero-width item matched which has a nextgroup, ! * don't push the item but set nextgroup. */ lspp = &(SYN_ITEMS(syn_block)[next_match_idx]); if (next_match_m_endpos.lnum == current_lnum && next_match_m_endpos.col == current_col --- 2132,2139 ---- { synpat_T *lspp; ! // When a zero-width item matched which has a nextgroup, ! // don't push the item but set nextgroup. lspp = &(SYN_ITEMS(syn_block)[next_match_idx]); if (next_match_m_endpos.lnum == current_lnum && next_match_m_endpos.col == current_col *************** *** 2146,2154 **** keep_next_list = TRUE; zero_width_next_list = TRUE; ! /* Add the index to a list, so that we can check ! * later that we don't match it again (and cause an ! * endless loop). */ if (ga_grow(&zero_width_next_ga, 1) == OK) { ((int *)(zero_width_next_ga.ga_data)) --- 2144,2152 ---- keep_next_list = TRUE; zero_width_next_list = TRUE; ! // Add the index to a list, so that we can check ! // later that we don't match it again (and cause an ! // endless loop). if (ga_grow(&zero_width_next_ga, 1) == OK) { ((int *)(zero_width_next_ga.ga_data)) *************** *** 2254,2261 **** */ if (syn_block->b_spell_cluster_id == 0) { ! /* There is no @Spell cluster: Do spelling for items without ! * @NoSpell cluster. */ if (syn_block->b_nospell_cluster_id == 0 || current_trans_id == 0) *can_spell = (syn_block->b_syn_spell != SYNSPL_NOTOP); --- 2252,2259 ---- */ if (syn_block->b_spell_cluster_id == 0) { ! // There is no @Spell cluster: Do spelling for items without ! // @NoSpell cluster. if (syn_block->b_nospell_cluster_id == 0 || current_trans_id == 0) *can_spell = (syn_block->b_syn_spell != SYNSPL_NOTOP); *************** *** 2269,2278 **** } else { ! /* The @Spell cluster is defined: Do spelling in items with ! * the @Spell cluster. But not when @NoSpell is also there. ! * At the toplevel only spell check when ":syn spell toplevel" ! * was used. */ if (current_trans_id == 0) *can_spell = (syn_block->b_syn_spell == SYNSPL_TOP); else --- 2267,2276 ---- } else { ! // The @Spell cluster is defined: Do spelling in items with ! // the @Spell cluster. But not when @NoSpell is also there. ! // At the toplevel only spell check when ":syn spell toplevel" ! // was used. if (current_trans_id == 0) *can_spell = (syn_block->b_syn_spell == SYNSPL_TOP); else *************** *** 2314,2326 **** } } else if (can_spell != NULL) ! /* Default: Only do spelling when there is no @Spell cluster or when ! * ":syn spell toplevel" was used. */ *can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT ? (syn_block->b_spell_cluster_id == 0) : (syn_block->b_syn_spell == SYNSPL_TOP); ! /* nextgroup ends at end of line, unless "skipnl" or "skipempty" present */ if (current_next_list != NULL && (line = syn_getcurline())[current_col] != NUL && line[current_col + 1] == NUL --- 2312,2324 ---- } } else if (can_spell != NULL) ! // Default: Only do spelling when there is no @Spell cluster or when ! // ":syn spell toplevel" was used. *can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT ? (syn_block->b_spell_cluster_id == 0) : (syn_block->b_syn_spell == SYNSPL_TOP); ! // nextgroup ends at end of line, unless "skipnl" or "skipempty" present if (current_next_list != NULL && (line = syn_getcurline())[current_col] != NUL && line[current_col + 1] == NUL *************** *** 2330,2336 **** if (zero_width_next_ga.ga_len > 0) ga_clear(&zero_width_next_ga); ! /* No longer need external matches. But keep next_match_extmatch. */ unref_extmatch(re_extmatch_out); re_extmatch_out = NULL; unref_extmatch(cur_extmatch); --- 2328,2334 ---- if (zero_width_next_ga.ga_len > 0) ga_clear(&zero_width_next_ga); ! // No longer need external matches. But keep next_match_extmatch. unref_extmatch(re_extmatch_out); re_extmatch_out = NULL; unref_extmatch(cur_extmatch); *************** *** 2353,2360 **** && CUR_STATE(i).si_idx == idx) return TRUE; ! /* Zero-width matches with a nextgroup argument are not put on the syntax ! * stack, and can only be matched once anyway. */ for (i = gap->ga_len; --i >= 0; ) if (((int *)(gap->ga_data))[i] == idx) return TRUE; --- 2351,2358 ---- && CUR_STATE(i).si_idx == idx) return TRUE; ! // Zero-width matches with a nextgroup argument are not put on the syntax ! // stack, and can only be matched once anyway. for (i = gap->ga_len; --i >= 0; ) if (((int *)(gap->ga_data))[i] == idx) return TRUE; *************** *** 2400,2406 **** cur_si->si_extmatch = ref_extmatch(next_match_extmatch); if (spp->sp_type == SPTYPE_START && !(spp->sp_flags & HL_ONELINE)) { ! /* Try to find the end pattern in the current line */ update_si_end(cur_si, (int)(next_match_m_endpos.col), TRUE); check_keepend(); } --- 2398,2404 ---- cur_si->si_extmatch = ref_extmatch(next_match_extmatch); if (spp->sp_type == SPTYPE_START && !(spp->sp_flags & HL_ONELINE)) { ! // Try to find the end pattern in the current line update_si_end(cur_si, (int)(next_match_m_endpos.col), TRUE); check_keepend(); } *************** *** 2450,2456 **** } } ! next_match_idx = -1; /* try other match next time */ return cur_si; } --- 2448,2454 ---- } } ! next_match_idx = -1; // try other match next time return cur_si; } *************** *** 2495,2520 **** #endif update_si_attr(current_state.ga_len - 1); ! /* nextgroup= should not match in the end pattern */ current_next_list = NULL; ! /* what matches next may be different now, clear it */ next_match_idx = 0; next_match_col = MAXCOL; break; } else { ! /* handle next_list, unless at end of line and no "skipnl" or ! * "skipempty" */ current_next_list = cur_si->si_next_list; current_next_flags = cur_si->si_flags; if (!(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY)) && syn_getcurline()[current_col] == NUL) current_next_list = NULL; ! /* When the ended item has "extend", another item with ! * "keepend" now needs to check for its end. */ had_extend = (cur_si->si_flags & HL_EXTEND); pop_current_state(); --- 2493,2518 ---- #endif update_si_attr(current_state.ga_len - 1); ! // nextgroup= should not match in the end pattern current_next_list = NULL; ! // what matches next may be different now, clear it next_match_idx = 0; next_match_col = MAXCOL; break; } else { ! // handle next_list, unless at end of line and no "skipnl" or ! // "skipempty" current_next_list = cur_si->si_next_list; current_next_flags = cur_si->si_flags; if (!(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY)) && syn_getcurline()[current_col] == NUL) current_next_list = NULL; ! // When the ended item has "extend", another item with ! // "keepend" now needs to check for its end. had_extend = (cur_si->si_flags & HL_EXTEND); pop_current_state(); *************** *** 2569,2575 **** stateitem_T *sip = &CUR_STATE(idx); synpat_T *spp; ! /* This should not happen... */ if (sip->si_idx < 0) return; --- 2567,2573 ---- stateitem_T *sip = &CUR_STATE(idx); synpat_T *spp; ! // This should not happen... if (sip->si_idx < 0) return; *************** *** 2681,2688 **** static void update_si_end( stateitem_T *sip, ! int startcol, /* where to start searching for the end */ ! int force) /* when TRUE overrule a previous end */ { lpos_T startpos; lpos_T endpos; --- 2679,2686 ---- static void update_si_end( stateitem_T *sip, ! int startcol, // where to start searching for the end ! int force) // when TRUE overrule a previous end { lpos_T startpos; lpos_T endpos; *************** *** 2690,2702 **** lpos_T end_endpos; int end_idx; ! /* return quickly for a keyword */ if (sip->si_idx < 0) return; ! /* Don't update when it's already done. Can be a match of an end pattern ! * that started in a previous line. Watch out: can also be a "keepend" ! * from a containing item. */ if (!force && sip->si_m_endpos.lnum >= current_lnum) return; --- 2688,2700 ---- lpos_T end_endpos; int end_idx; ! // return quickly for a keyword if (sip->si_idx < 0) return; ! // Don't update when it's already done. Can be a match of an end pattern ! // that started in a previous line. Watch out: can also be a "keepend" ! // from a containing item. if (!force && sip->si_m_endpos.lnum >= current_lnum) return; *************** *** 2712,2728 **** if (endpos.lnum == 0) { ! /* No end pattern matched. */ if (SYN_ITEMS(syn_block)[sip->si_idx].sp_flags & HL_ONELINE) { ! /* a "oneline" never continues in the next line */ sip->si_ends = TRUE; sip->si_m_endpos.lnum = current_lnum; sip->si_m_endpos.col = (colnr_T)STRLEN(syn_getcurline()); } else { ! /* continues in the next line */ sip->si_ends = FALSE; sip->si_m_endpos.lnum = 0; } --- 2710,2726 ---- if (endpos.lnum == 0) { ! // No end pattern matched. if (SYN_ITEMS(syn_block)[sip->si_idx].sp_flags & HL_ONELINE) { ! // a "oneline" never continues in the next line sip->si_ends = TRUE; sip->si_m_endpos.lnum = current_lnum; sip->si_m_endpos.col = (colnr_T)STRLEN(syn_getcurline()); } else { ! // continues in the next line sip->si_ends = FALSE; sip->si_m_endpos.lnum = 0; } *************** *** 2730,2736 **** } else { ! /* match within this line */ sip->si_m_endpos = endpos; sip->si_h_endpos = hl_endpos; sip->si_eoe_pos = end_endpos; --- 2728,2734 ---- } else { ! // match within this line sip->si_m_endpos = endpos; sip->si_h_endpos = hl_endpos; sip->si_eoe_pos = end_endpos; *************** *** 2766,2775 **** unref_extmatch(CUR_STATE(current_state.ga_len - 1).si_extmatch); --current_state.ga_len; } ! /* after the end of a pattern, try matching a keyword or pattern */ next_match_idx = -1; ! /* if first state with "keepend" is popped, reset keepend_level */ if (keepend_level >= current_state.ga_len) keepend_level = -1; } --- 2764,2773 ---- unref_extmatch(CUR_STATE(current_state.ga_len - 1).si_extmatch); --current_state.ga_len; } ! // after the end of a pattern, try matching a keyword or pattern next_match_idx = -1; ! // if first state with "keepend" is popped, reset keepend_level if (keepend_level >= current_state.ga_len) keepend_level = -1; } *************** *** 2785,2811 **** */ static void find_endpos( ! int idx, /* index of the pattern */ ! lpos_T *startpos, /* where to start looking for an END match */ ! lpos_T *m_endpos, /* return: end of match */ ! lpos_T *hl_endpos, /* return: end of highlighting */ ! long *flagsp, /* return: flags of matching END */ ! lpos_T *end_endpos, /* return: end of end pattern match */ ! int *end_idx, /* return: group ID for end pat. match, or 0 */ ! reg_extmatch_T *start_ext) /* submatches from the start pattern */ { colnr_T matchcol; synpat_T *spp, *spp_skip; int start_idx; int best_idx; regmmatch_T regmatch; ! regmmatch_T best_regmatch; /* startpos/endpos of best match */ lpos_T pos; char_u *line; int had_match = FALSE; ! char_u buf_chartab[32]; /* chartab array for syn option iskyeyword */ ! /* just in case we are invoked for a keyword */ if (idx < 0) return; --- 2783,2809 ---- */ static void find_endpos( ! int idx, // index of the pattern ! lpos_T *startpos, // where to start looking for an END match ! lpos_T *m_endpos, // return: end of match ! lpos_T *hl_endpos, // return: end of highlighting ! long *flagsp, // return: flags of matching END ! lpos_T *end_endpos, // return: end of end pattern match ! int *end_idx, // return: group ID for end pat. match, or 0 ! reg_extmatch_T *start_ext) // submatches from the start pattern { colnr_T matchcol; synpat_T *spp, *spp_skip; int start_idx; int best_idx; regmmatch_T regmatch; ! regmmatch_T best_regmatch; // startpos/endpos of best match lpos_T pos; char_u *line; int had_match = FALSE; ! char_u buf_chartab[32]; // chartab array for syn option iskyeyword ! // just in case we are invoked for a keyword if (idx < 0) return; *************** *** 2843,2857 **** else spp_skip = NULL; ! /* Setup external matches for syn_regexec(). */ unref_extmatch(re_extmatch_in); re_extmatch_in = ref_extmatch(start_ext); ! matchcol = startpos->col; /* start looking for a match at sstart */ ! start_idx = idx; /* remember the first END pattern. */ ! best_regmatch.startpos[0].col = 0; /* avoid compiler warning */ ! /* use syntax iskeyword option */ save_chartab(buf_chartab); for (;;) --- 2841,2855 ---- else spp_skip = NULL; ! // Setup external matches for syn_regexec(). unref_extmatch(re_extmatch_in); re_extmatch_in = ref_extmatch(start_ext); ! matchcol = startpos->col; // start looking for a match at sstart ! start_idx = idx; // remember the first END pattern. ! best_regmatch.startpos[0].col = 0; // avoid compiler warning ! // use syntax iskeyword option save_chartab(buf_chartab); for (;;) *************** *** 2866,2872 **** int r; spp = &(SYN_ITEMS(syn_block)[idx]); ! if (spp->sp_type != SPTYPE_END) /* past last END pattern */ break; lc_col -= spp->sp_offsets[SPO_LC_OFF]; if (lc_col < 0) --- 2864,2870 ---- int r; spp = &(SYN_ITEMS(syn_block)[idx]); ! if (spp->sp_type != SPTYPE_END) // past last END pattern break; lc_col -= spp->sp_offsets[SPO_LC_OFF]; if (lc_col < 0) *************** *** 2917,2950 **** { int line_len; ! /* Add offset to skip pattern match */ syn_add_end_off(&pos, ®match, spp_skip, SPO_ME_OFF, 1); ! /* If the skip pattern goes on to the next line, there is no ! * match with an end pattern in this line. */ if (pos.lnum > startpos->lnum) break; line = ml_get_buf(syn_buf, startpos->lnum, FALSE); line_len = (int)STRLEN(line); ! /* take care of an empty match or negative offset */ if (pos.col <= matchcol) ++matchcol; else if (pos.col <= regmatch.endpos[0].col) matchcol = pos.col; else ! /* Be careful not to jump over the NUL at the end-of-line */ for (matchcol = regmatch.endpos[0].col; matchcol < line_len && matchcol < pos.col; ++matchcol) ; ! /* if the skip pattern includes end-of-line, break here */ if (matchcol >= line_len) break; ! continue; /* start with first end pattern again */ } } --- 2915,2948 ---- { int line_len; ! // Add offset to skip pattern match syn_add_end_off(&pos, ®match, spp_skip, SPO_ME_OFF, 1); ! // If the skip pattern goes on to the next line, there is no ! // match with an end pattern in this line. if (pos.lnum > startpos->lnum) break; line = ml_get_buf(syn_buf, startpos->lnum, FALSE); line_len = (int)STRLEN(line); ! // take care of an empty match or negative offset if (pos.col <= matchcol) ++matchcol; else if (pos.col <= regmatch.endpos[0].col) matchcol = pos.col; else ! // Be careful not to jump over the NUL at the end-of-line for (matchcol = regmatch.endpos[0].col; matchcol < line_len && matchcol < pos.col; ++matchcol) ; ! // if the skip pattern includes end-of-line, break here if (matchcol >= line_len) break; ! continue; // start with first end pattern again } } *************** *** 2954,2969 **** */ spp = &(SYN_ITEMS(syn_block)[best_idx]); syn_add_end_off(m_endpos, &best_regmatch, spp, SPO_ME_OFF, 1); ! /* can't end before the start */ if (m_endpos->lnum == startpos->lnum && m_endpos->col < startpos->col) m_endpos->col = startpos->col; syn_add_end_off(end_endpos, &best_regmatch, spp, SPO_HE_OFF, 1); ! /* can't end before the start */ if (end_endpos->lnum == startpos->lnum && end_endpos->col < startpos->col) end_endpos->col = startpos->col; ! /* can't end after the match */ limit_pos(end_endpos, m_endpos); /* --- 2952,2967 ---- */ spp = &(SYN_ITEMS(syn_block)[best_idx]); syn_add_end_off(m_endpos, &best_regmatch, spp, SPO_ME_OFF, 1); ! // can't end before the start if (m_endpos->lnum == startpos->lnum && m_endpos->col < startpos->col) m_endpos->col = startpos->col; syn_add_end_off(end_endpos, &best_regmatch, spp, SPO_HE_OFF, 1); ! // can't end before the start if (end_endpos->lnum == startpos->lnum && end_endpos->col < startpos->col) end_endpos->col = startpos->col; ! // can't end after the match limit_pos(end_endpos, m_endpos); /* *************** *** 2984,2997 **** } hl_endpos->col += spp->sp_offsets[SPO_RE_OFF]; ! /* can't end before the start */ if (hl_endpos->lnum == startpos->lnum && hl_endpos->col < startpos->col) hl_endpos->col = startpos->col; limit_pos(hl_endpos, m_endpos); ! /* now the match ends where the highlighting ends, it is turned ! * into the matchgroup for the end */ *m_endpos = *hl_endpos; } else --- 2982,2995 ---- } hl_endpos->col += spp->sp_offsets[SPO_RE_OFF]; ! // can't end before the start if (hl_endpos->lnum == startpos->lnum && hl_endpos->col < startpos->col) hl_endpos->col = startpos->col; limit_pos(hl_endpos, m_endpos); ! // now the match ends where the highlighting ends, it is turned ! // into the matchgroup for the end *m_endpos = *hl_endpos; } else *************** *** 3006,3018 **** break; } ! /* no match for an END pattern in this line */ if (!had_match) m_endpos->lnum = 0; restore_chartab(buf_chartab); ! /* Remove external matches. */ unref_extmatch(re_extmatch_in); re_extmatch_in = NULL; } --- 3004,3016 ---- break; } ! // no match for an END pattern in this line if (!had_match) m_endpos->lnum = 0; restore_chartab(buf_chartab); ! // Remove external matches. unref_extmatch(re_extmatch_in); re_extmatch_in = NULL; } *************** *** 3048,3058 **** */ static void syn_add_end_off( ! lpos_T *result, /* returned position */ ! regmmatch_T *regmatch, /* start/end of match */ ! synpat_T *spp, /* matched pattern */ ! int idx, /* index of offset */ ! int extra) /* extra chars for offset to start */ { int col; int off; --- 3046,3056 ---- */ static void syn_add_end_off( ! lpos_T *result, // returned position ! regmmatch_T *regmatch, // start/end of match ! synpat_T *spp, // matched pattern ! int idx, // index of offset ! int extra) // extra chars for offset to start { int col; int off; *************** *** 3071,3078 **** col = regmatch->endpos[0].col; off = spp->sp_offsets[idx]; } ! /* Don't go past the end of the line. Matters for "rs=e+2" when there ! * is a matchgroup. Watch out for match with last NL in the buffer. */ if (result->lnum > syn_buf->b_ml.ml_line_count) col = 0; else if (off != 0) --- 3069,3076 ---- col = regmatch->endpos[0].col; off = spp->sp_offsets[idx]; } ! // Don't go past the end of the line. Matters for "rs=e+2" when there ! // is a matchgroup. Watch out for match with last NL in the buffer. if (result->lnum > syn_buf->b_ml.ml_line_count) col = 0; else if (off != 0) *************** *** 3100,3110 **** */ static void syn_add_start_off( ! lpos_T *result, /* returned position */ ! regmmatch_T *regmatch, /* start/end of match */ synpat_T *spp, int idx, ! int extra) /* extra chars for offset to end */ { int col; int off; --- 3098,3108 ---- */ static void syn_add_start_off( ! lpos_T *result, // returned position ! regmmatch_T *regmatch, // start/end of match synpat_T *spp, int idx, ! int extra) // extra chars for offset to end { int col; int off; *************** *** 3125,3131 **** } if (result->lnum > syn_buf->b_ml.ml_line_count) { ! /* a "\n" at the end of the pattern may take us below the last line */ result->lnum = syn_buf->b_ml.ml_line_count; col = (int)STRLEN(ml_get_buf(syn_buf, result->lnum, FALSE)); } --- 3123,3129 ---- } if (result->lnum > syn_buf->b_ml.ml_line_count) { ! // a "\n" at the end of the pattern may take us below the last line result->lnum = syn_buf->b_ml.ml_line_count; col = (int)STRLEN(ml_get_buf(syn_buf, result->lnum, FALSE)); } *************** *** 3231,3253 **** static int check_keyword_id( char_u *line, ! int startcol, /* position in line to check for keyword */ ! int *endcolp, /* return: character after found keyword */ ! long *flagsp, /* return: flags of matching keyword */ ! short **next_listp, /* return: next_list of matching keyword */ ! stateitem_T *cur_si, /* item at the top of the stack */ ! int *ccharp UNUSED) /* conceal substitution char */ { keyentry_T *kp; char_u *kwp; int round; int kwlen; ! char_u keyword[MAXKEYWLEN + 1]; /* assume max. keyword len is 80 */ hashtab_T *ht; hashitem_T *hi; ! /* Find first character after the keyword. First character was already ! * checked. */ kwp = line + startcol; kwlen = 0; do --- 3229,3251 ---- static int check_keyword_id( char_u *line, ! int startcol, // position in line to check for keyword ! int *endcolp, // return: character after found keyword ! long *flagsp, // return: flags of matching keyword ! short **next_listp, // return: next_list of matching keyword ! stateitem_T *cur_si, // item at the top of the stack ! int *ccharp UNUSED) // conceal substitution char { keyentry_T *kp; char_u *kwp; int round; int kwlen; ! char_u keyword[MAXKEYWLEN + 1]; // assume max. keyword len is 80 hashtab_T *ht; hashitem_T *hi; ! // Find first character after the keyword. First character was already ! // checked. kwp = line + startcol; kwlen = 0; do *************** *** 3278,3284 **** ht = round == 1 ? &syn_block->b_keywtab : &syn_block->b_keywtab_ic; if (ht->ht_used == 0) continue; ! if (round == 2) /* ignore case */ (void)str_foldcase(kwp, kwlen, keyword, MAXKEYWLEN + 1); /* --- 3276,3282 ---- ht = round == 1 ? &syn_block->b_keywtab : &syn_block->b_keywtab_ic; if (ht->ht_used == 0) continue; ! if (round == 2) // ignore case (void)str_foldcase(kwp, kwlen, keyword, MAXKEYWLEN + 1); /* *************** *** 3407,3413 **** return; } ! /* assume spell checking changed, force a redraw */ redraw_win_later(curwin, NOT_VALID); } --- 3405,3411 ---- return; } ! // assume spell checking changed, force a redraw redraw_win_later(curwin, NOT_VALID); } *************** *** 3470,3496 **** { int i; ! block->b_syn_error = FALSE; /* clear previous error */ #ifdef FEAT_RELTIME ! block->b_syn_slow = FALSE; /* clear previous timeout */ #endif ! block->b_syn_ic = FALSE; /* Use case, by default */ ! block->b_syn_spell = SYNSPL_DEFAULT; /* default spell checking */ block->b_syn_containedin = FALSE; #ifdef FEAT_CONCEAL block->b_syn_conceal = FALSE; #endif ! /* free the keywords */ clear_keywtab(&block->b_keywtab); clear_keywtab(&block->b_keywtab_ic); ! /* free the syntax patterns */ for (i = block->b_syn_patterns.ga_len; --i >= 0; ) syn_clear_pattern(block, i); ga_clear(&block->b_syn_patterns); ! /* free the syntax clusters */ for (i = block->b_syn_clusters.ga_len; --i >= 0; ) syn_clear_cluster(block, i); ga_clear(&block->b_syn_clusters); --- 3468,3494 ---- { int i; ! block->b_syn_error = FALSE; // clear previous error #ifdef FEAT_RELTIME ! block->b_syn_slow = FALSE; // clear previous timeout #endif ! block->b_syn_ic = FALSE; // Use case, by default ! block->b_syn_spell = SYNSPL_DEFAULT; // default spell checking block->b_syn_containedin = FALSE; #ifdef FEAT_CONCEAL block->b_syn_conceal = FALSE; #endif ! // free the keywords clear_keywtab(&block->b_keywtab); clear_keywtab(&block->b_keywtab_ic); ! // free the syntax patterns for (i = block->b_syn_patterns.ga_len; --i >= 0; ) syn_clear_pattern(block, i); ga_clear(&block->b_syn_patterns); ! // free the syntax clusters for (i = block->b_syn_clusters.ga_len; --i >= 0; ) syn_clear_cluster(block, i); ga_clear(&block->b_syn_clusters); *************** *** 3510,3520 **** #endif clear_string_option(&block->b_syn_isk); ! /* free the stored states */ syn_stack_free_all(block); invalidate_current_state(); ! /* Reset the counter for ":syn include" */ running_syn_inc_tag = 0; } --- 3508,3518 ---- #endif clear_string_option(&block->b_syn_isk); ! // free the stored states syn_stack_free_all(block); invalidate_current_state(); ! // Reset the counter for ":syn include" running_syn_inc_tag = 0; } *************** *** 3540,3546 **** { int i; ! /* free the syntax patterns */ for (i = curwin->w_s->b_syn_patterns.ga_len; --i >= 0; ) if (SYN_ITEMS(curwin->w_s)[i].sp_syncing) syn_remove_pattern(curwin->w_s, i); --- 3538,3544 ---- { int i; ! // free the syntax patterns for (i = curwin->w_s->b_syn_patterns.ga_len; --i >= 0; ) if (SYN_ITEMS(curwin->w_s)[i].sp_syncing) syn_remove_pattern(curwin->w_s, i); *************** *** 3555,3561 **** VIM_CLEAR(curwin->w_s->b_syn_linecont_pat); clear_string_option(&curwin->w_s->b_syn_isk); ! syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */ } /* --- 3553,3559 ---- VIM_CLEAR(curwin->w_s->b_syn_linecont_pat); clear_string_option(&curwin->w_s->b_syn_isk); ! syn_stack_free_all(curwin->w_s); // Need to recompute all syntax. } /* *************** *** 3588,3594 **** { vim_free(SYN_ITEMS(block)[i].sp_pattern); vim_regfree(SYN_ITEMS(block)[i].sp_prog); ! /* Only free sp_cont_list and sp_next_list of first start pattern */ if (i == 0 || SYN_ITEMS(block)[i - 1].sp_type != SPTYPE_START) { vim_free(SYN_ITEMS(block)[i].sp_cont_list); --- 3586,3592 ---- { vim_free(SYN_ITEMS(block)[i].sp_pattern); vim_regfree(SYN_ITEMS(block)[i].sp_prog); ! // Only free sp_cont_list and sp_next_list of first start pattern if (i == 0 || SYN_ITEMS(block)[i - 1].sp_type != SPTYPE_START) { vim_free(SYN_ITEMS(block)[i].sp_cont_list); *************** *** 3689,3695 **** } } redraw_curbuf_later(SOME_VALID); ! syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */ } /* --- 3687,3693 ---- } } redraw_curbuf_later(SOME_VALID); ! syn_stack_free_all(curwin->w_s); // Need to recompute all syntax. } /* *************** *** 3701,3714 **** synpat_T *spp; int idx; ! /* Clear keywords only when not ":syn sync clear group-name" */ if (!syncing) { (void)syn_clear_keyword(id, &curwin->w_s->b_keywtab); (void)syn_clear_keyword(id, &curwin->w_s->b_keywtab_ic); } ! /* clear the patterns for "id" */ for (idx = curwin->w_s->b_syn_patterns.ga_len; --idx >= 0; ) { spp = &(SYN_ITEMS(curwin->w_s)[idx]); --- 3699,3712 ---- synpat_T *spp; int idx; ! // Clear keywords only when not ":syn sync clear group-name" if (!syncing) { (void)syn_clear_keyword(id, &curwin->w_s->b_keywtab); (void)syn_clear_keyword(id, &curwin->w_s->b_keywtab_ic); } ! // clear the patterns for "id" for (idx = curwin->w_s->b_syn_patterns.ga_len; --idx >= 0; ) { spp = &(SYN_ITEMS(curwin->w_s)[idx]); *************** *** 3792,3798 **** static void syn_cmd_list( exarg_T *eap, ! int syncing) /* when TRUE: list syncing items */ { char_u *arg = eap->arg; int id; --- 3790,3796 ---- static void syn_cmd_list( exarg_T *eap, ! int syncing) // when TRUE: list syncing items { char_u *arg = eap->arg; int id; *************** *** 3932,3939 **** static void syn_list_one( int id, ! int syncing, /* when TRUE: list syncing items */ ! int link_only) /* when TRUE; list link-only too */ { int attr; int idx; --- 3930,3937 ---- static void syn_list_one( int id, ! int syncing, // when TRUE: list syncing items ! int link_only) // when TRUE; list link-only too { int attr; int idx; *************** *** 3963,3971 **** {0, NULL} }; ! attr = HL_ATTR(HLF_D); /* highlight like directories */ ! /* list the keywords for "id" */ if (!syncing) { did_header = syn_list_keywords(id, &curwin->w_s->b_keywtab, FALSE, attr); --- 3961,3969 ---- {0, NULL} }; ! attr = HL_ATTR(HLF_D); // highlight like directories ! // list the keywords for "id" if (!syncing) { did_header = syn_list_keywords(id, &curwin->w_s->b_keywtab, FALSE, attr); *************** *** 3973,3979 **** did_header, attr); } ! /* list the patterns for "id" */ for (idx = 0; idx < curwin->w_s->b_syn_patterns.ga_len && !got_int; ++idx) { spp = &(SYN_ITEMS(curwin->w_s)[idx]); --- 3971,3977 ---- did_header, attr); } ! // list the patterns for "id" for (idx = 0; idx < curwin->w_s->b_syn_patterns.ga_len && !got_int; ++idx) { spp = &(SYN_ITEMS(curwin->w_s)[idx]); *************** *** 4030,4036 **** } } ! /* list the link, if there is one */ if (highlight_link_id(id - 1) && (did_header || link_only) && !got_int) { (void)syn_list_header(did_header, 999, id); --- 4028,4034 ---- } } ! // list the link, if there is one if (highlight_link_id(id - 1) && (did_header || link_only) && !got_int) { (void)syn_list_header(did_header, 999, id); *************** *** 4061,4073 **** { int endcol = 15; ! /* slight hack: roughly duplicate the guts of syn_list_header() */ msg_putchar('\n'); msg_outtrans(SYN_CLSTR(curwin->w_s)[id].scl_name); ! if (msg_col >= endcol) /* output at least one space */ endcol = msg_col + 1; ! if (Columns <= endcol) /* avoid hang for tiny window */ endcol = Columns - 1; msg_advance(endcol); --- 4059,4071 ---- { int endcol = 15; ! // slight hack: roughly duplicate the guts of syn_list_header() msg_putchar('\n'); msg_outtrans(SYN_CLSTR(curwin->w_s)[id].scl_name); ! if (msg_col >= endcol) // output at least one space endcol = msg_col + 1; ! if (Columns <= endcol) // avoid hang for tiny window endcol = Columns - 1; msg_advance(endcol); *************** *** 4135,4141 **** static char *sepchars = "/+=-#@\"|'^&"; int i; ! /* May have to write "matchgroup=group" */ if (last_matchgroup != spp->sp_syn_match_id) { last_matchgroup = spp->sp_syn_match_id; --- 4133,4139 ---- static char *sepchars = "/+=-#@\"|'^&"; int i; ! // May have to write "matchgroup=group" if (last_matchgroup != spp->sp_syn_match_id) { last_matchgroup = spp->sp_syn_match_id; *************** *** 4148,4169 **** msg_putchar(' '); } ! /* output the name of the pattern and an '=' or ' ' */ msg_puts_attr(s, attr); msg_putchar(c); ! /* output the pattern, in between a char that is not in the pattern */ for (i = 0; vim_strchr(spp->sp_pattern, sepchars[i]) != NULL; ) if (sepchars[++i] == NUL) { ! i = 0; /* no good char found, just use the first one */ break; } msg_putchar(sepchars[i]); msg_outtrans(spp->sp_pattern); msg_putchar(sepchars[i]); ! /* output any pattern options */ first = TRUE; for (i = 0; i < SPO_COUNT; ++i) { --- 4146,4167 ---- msg_putchar(' '); } ! // output the name of the pattern and an '=' or ' ' msg_puts_attr(s, attr); msg_putchar(c); ! // output the pattern, in between a char that is not in the pattern for (i = 0; vim_strchr(spp->sp_pattern, sepchars[i]) != NULL; ) if (sepchars[++i] == NUL) { ! i = 0; // no good char found, just use the first one break; } msg_putchar(sepchars[i]); msg_outtrans(spp->sp_pattern); msg_putchar(sepchars[i]); ! // output any pattern options first = TRUE; for (i = 0; i < SPO_COUNT; ++i) { *************** *** 4171,4177 **** if (spp->sp_off_flags & (mask + (mask << SPO_COUNT))) { if (!first) ! msg_putchar(','); /* separate with commas */ msg_puts(spo_name_tab[i]); n = spp->sp_offsets[i]; if (i != SPO_LC_OFF) --- 4169,4175 ---- if (spp->sp_off_flags & (mask + (mask << SPO_COUNT))) { if (!first) ! msg_putchar(','); // separate with commas msg_puts(spo_name_tab[i]); n = spp->sp_offsets[i]; if (i != SPO_LC_OFF) *************** *** 4199,4205 **** syn_list_keywords( int id, hashtab_T *ht, ! int did_header, /* header has already been printed */ int attr) { int outlen; --- 4197,4203 ---- syn_list_keywords( int id, hashtab_T *ht, ! int did_header, // header has already been printed int attr) { int outlen; *************** *** 4236,4242 **** outlen = 9999; else outlen = (int)STRLEN(kp->keyword); ! /* output "contained" and "nextgroup" on each line */ if (syn_list_header(did_header, outlen, id)) { prev_contained = 0; --- 4234,4240 ---- outlen = 9999; else outlen = (int)STRLEN(kp->keyword); ! // output "contained" and "nextgroup" on each line if (syn_list_header(did_header, outlen, id)) { prev_contained = 0; *************** *** 4375,4385 **** */ static void add_keyword( ! char_u *name, /* name of keyword */ ! int id, /* group ID for this keyword */ ! int flags, /* flags for this keyword */ ! short *cont_in_list, /* containedin for this keyword */ ! short *next_list, /* nextgroup for this keyword */ int conceal_char) { keyentry_T *kp; --- 4373,4383 ---- */ static void add_keyword( ! char_u *name, // name of keyword ! int id, // group ID for this keyword ! int flags, // flags for this keyword ! short *cont_in_list, // containedin for this keyword ! short *next_list, // nextgroup for this keyword int conceal_char) { keyentry_T *kp; *************** *** 4416,4428 **** hi = hash_lookup(ht, kp->keyword, hash); if (HASHITEM_EMPTY(hi)) { ! /* new keyword, add to hashtable */ kp->ke_next = NULL; hash_add_item(ht, hi, kp->keyword, hash); } else { ! /* keyword already exists, prepend to list */ kp->ke_next = HI2KE(hi); hi->hi_key = KE2HIKEY(kp); } --- 4414,4426 ---- hi = hash_lookup(ht, kp->keyword, hash); if (HASHITEM_EMPTY(hi)) { ! // new keyword, add to hashtable kp->ke_next = NULL; hash_add_item(ht, hi, kp->keyword, hash); } else { ! // keyword already exists, prepend to list kp->ke_next = HI2KE(hi); hi->hi_key = KE2HIKEY(kp); } *************** *** 4435,4442 **** */ static char_u * get_group_name( ! char_u *arg, /* start of the argument */ ! char_u **name_end) /* pointer to end of the name */ { char_u *rest; --- 4433,4440 ---- */ static char_u * get_group_name( ! char_u *arg, // start of the argument ! char_u **name_end) // pointer to end of the name { char_u *rest; *************** *** 4462,4471 **** */ static char_u * get_syn_options( ! char_u *arg, /* next argument to be checked */ ! syn_opt_arg_T *opt, /* various things */ int *conceal_char UNUSED, ! int skip) /* TRUE if skipping over command */ { char_u *gname_start, *gname; int syn_id; --- 4460,4469 ---- */ static char_u * get_syn_options( ! char_u *arg, // next argument to be checked ! syn_opt_arg_T *opt, // various things int *conceal_char UNUSED, ! int skip) // TRUE if skipping over command { char_u *gname_start, *gname; int syn_id; *************** *** 4500,4506 **** }; static char *first_letters = "cCoOkKeEtTsSgGdDfFnN"; ! if (arg == NULL) /* already detected error */ return NULL; #ifdef FEAT_CONCEAL --- 4498,4504 ---- }; static char *first_letters = "cCoOkKeEtTsSgGdDfFnN"; ! if (arg == NULL) // already detected error return NULL; #ifdef FEAT_CONCEAL *************** *** 4533,4544 **** && (flagtab[fidx].flags == HL_DISPLAY || flagtab[fidx].flags == HL_FOLD || flagtab[fidx].flags == HL_EXTEND)) ! /* treat "display", "fold" and "extend" as a keyword */ fidx = -1; break; } } ! if (fidx < 0) /* no match found */ break; if (flagtab[fidx].argtype == 1) --- 4531,4542 ---- && (flagtab[fidx].flags == HL_DISPLAY || flagtab[fidx].flags == HL_FOLD || flagtab[fidx].flags == HL_EXTEND)) ! // treat "display", "fold" and "extend" as a keyword fidx = -1; break; } } ! if (fidx < 0) // no match found break; if (flagtab[fidx].argtype == 1) *************** *** 4563,4569 **** } else if (flagtab[fidx].argtype == 11 && arg[5] == '=') { ! /* cchar=? */ if (has_mbyte) { #ifdef FEAT_CONCEAL --- 4561,4567 ---- } else if (flagtab[fidx].argtype == 11 && arg[5] == '=') { ! // cchar=? if (has_mbyte) { #ifdef FEAT_CONCEAL *************** *** 4634,4640 **** #ifdef FEAT_FOLDING else if (flagtab[fidx].flags == HL_FOLD && foldmethodIsSyntax(curwin)) ! /* Need to update folds later. */ foldUpdateAll(curwin); #endif } --- 4632,4638 ---- #ifdef FEAT_FOLDING else if (flagtab[fidx].flags == HL_FOLD && foldmethodIsSyntax(curwin)) ! // Need to update folds later. foldUpdateAll(curwin); #endif } *************** *** 4656,4662 **** *flagsp |= HL_CONTAINED; if (curwin->w_s->b_syn_topgrp >= SYNID_CLUSTER) { ! /* We have to alloc this, because syn_combine_list() will free it. */ short *grp_list = ALLOC_MULT(short, 2); int tlg_id = curwin->w_s->b_syn_topgrp - SYNID_CLUSTER; --- 4654,4660 ---- *flagsp |= HL_CONTAINED; if (curwin->w_s->b_syn_topgrp >= SYNID_CLUSTER) { ! // We have to alloc this, because syn_combine_list() will free it. short *grp_list = ALLOC_MULT(short, 2); int tlg_id = curwin->w_s->b_syn_topgrp - SYNID_CLUSTER; *************** *** 4701,4707 **** sgl_id = syn_check_cluster(arg, (int)(group_name_end - arg)); if (sgl_id == 0) return; ! /* separate_nextcmd() and expand_filename() depend on this */ eap->arg = rest; } --- 4699,4705 ---- sgl_id = syn_check_cluster(arg, (int)(group_name_end - arg)); if (sgl_id == 0) return; ! // separate_nextcmd() and expand_filename() depend on this eap->arg = rest; } *************** *** 4713,4721 **** separate_nextcmd(eap); if (*eap->arg == '<' || *eap->arg == '$' || mch_isFullName(eap->arg)) { ! /* For an absolute path, "$VIM/..." or ".." we ":source" the ! * file. Need to expand the file name first. In other cases ! * ":runtime!" is used. */ source = TRUE; if (expand_filename(eap, syn_cmdlinep, &errormsg) == FAIL) { --- 4711,4719 ---- separate_nextcmd(eap); if (*eap->arg == '<' || *eap->arg == '$' || mch_isFullName(eap->arg)) { ! // For an absolute path, "$VIM/..." or ".." we ":source" the ! // file. Need to expand the file name first. In other cases ! // ":runtime!" is used. source = TRUE; if (expand_filename(eap, syn_cmdlinep, &errormsg) == FAIL) { *************** *** 4771,4777 **** else syn_id = syn_check_group(arg, (int)(group_name_end - arg)); if (syn_id != 0) ! /* allocate a buffer, for removing backslashes in the keyword */ keyword_copy = alloc(STRLEN(rest) + 1); if (keyword_copy != NULL) { --- 4769,4775 ---- else syn_id = syn_check_group(arg, (int)(group_name_end - arg)); if (syn_id != 0) ! // allocate a buffer, for removing backslashes in the keyword keyword_copy = alloc(STRLEN(rest) + 1); if (keyword_copy != NULL) { *************** *** 4795,4801 **** eap->skip); if (rest == NULL || ends_excmd(*rest)) break; ! /* Copy the keyword, removing backslashes, and add a NUL. */ while (*rest != NUL && !VIM_ISWHITE(*rest)) { if (*rest == '\\' && rest[1] != NUL) --- 4793,4799 ---- eap->skip); if (rest == NULL || ends_excmd(*rest)) break; ! // Copy the keyword, removing backslashes, and add a NUL. while (*rest != NUL && !VIM_ISWHITE(*rest)) { if (*rest == '\\' && rest[1] != NUL) *************** *** 4808,4814 **** if (!eap->skip) { ! /* Adjust flags for use of ":syn include". */ syn_incl_toplevel(syn_id, &syn_opt_arg.flags); /* --- 4806,4812 ---- if (!eap->skip) { ! // Adjust flags for use of ":syn include". syn_incl_toplevel(syn_id, &syn_opt_arg.flags); /* *************** *** 4838,4844 **** kw, &p[2]); goto error; } ! kw = p + 1; /* skip over the "]" */ break; } if (has_mbyte) --- 4836,4842 ---- kw, &p[2]); goto error; } ! kw = p + 1; // skip over the "]" break; } if (has_mbyte) *************** *** 4869,4875 **** semsg(_(e_invarg2), arg); redraw_curbuf_later(SOME_VALID); ! syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */ } /* --- 4867,4873 ---- semsg(_(e_invarg2), arg); redraw_curbuf_later(SOME_VALID); ! syn_stack_free_all(curwin->w_s); // Need to recompute all syntax. } /* *************** *** 4880,4901 **** static void syn_cmd_match( exarg_T *eap, ! int syncing) /* TRUE for ":syntax sync match .. " */ { char_u *arg = eap->arg; char_u *group_name_end; char_u *rest; ! synpat_T item; /* the item found in the line */ int syn_id; int idx; syn_opt_arg_T syn_opt_arg; int sync_idx = 0; int conceal_char = NUL; ! /* Isolate the group name, check for validity */ rest = get_group_name(arg, &group_name_end); ! /* Get options before the pattern */ syn_opt_arg.flags = 0; syn_opt_arg.keyword = FALSE; syn_opt_arg.sync_idx = syncing ? &sync_idx : NULL; --- 4878,4899 ---- static void syn_cmd_match( exarg_T *eap, ! int syncing) // TRUE for ":syntax sync match .. " { char_u *arg = eap->arg; char_u *group_name_end; char_u *rest; ! synpat_T item; // the item found in the line int syn_id; int idx; syn_opt_arg_T syn_opt_arg; int sync_idx = 0; int conceal_char = NUL; ! // Isolate the group name, check for validity rest = get_group_name(arg, &group_name_end); ! // Get options before the pattern syn_opt_arg.flags = 0; syn_opt_arg.keyword = FALSE; syn_opt_arg.sync_idx = syncing ? &sync_idx : NULL; *************** *** 4905,4921 **** syn_opt_arg.next_list = NULL; rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip); ! /* get the pattern. */ init_syn_patterns(); vim_memset(&item, 0, sizeof(item)); rest = get_syn_pattern(rest, &item); if (vim_regcomp_had_eol() && !(syn_opt_arg.flags & HL_EXCLUDENL)) syn_opt_arg.flags |= HL_HAS_EOL; ! /* Get options after the pattern */ rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip); ! if (rest != NULL) /* all arguments are valid */ { /* * Check for trailing command and illegal trailing arguments. --- 4903,4919 ---- syn_opt_arg.next_list = NULL; rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip); ! // get the pattern. init_syn_patterns(); vim_memset(&item, 0, sizeof(item)); rest = get_syn_pattern(rest, &item); if (vim_regcomp_had_eol() && !(syn_opt_arg.flags & HL_EXCLUDENL)) syn_opt_arg.flags |= HL_HAS_EOL; ! // Get options after the pattern rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip); ! if (rest != NULL) // all arguments are valid { /* * Check for trailing command and illegal trailing arguments. *************** *** 4950,4956 **** SYN_ITEMS(curwin->w_s)[idx].sp_next_list = syn_opt_arg.next_list; ++curwin->w_s->b_syn_patterns.ga_len; ! /* remember that we found a match for syncing on */ if (syn_opt_arg.flags & (HL_SYNC_HERE|HL_SYNC_THERE)) curwin->w_s->b_syn_sync_flags |= SF_MATCH; #ifdef FEAT_FOLDING --- 4948,4954 ---- SYN_ITEMS(curwin->w_s)[idx].sp_next_list = syn_opt_arg.next_list; ++curwin->w_s->b_syn_patterns.ga_len; ! // remember that we found a match for syncing on if (syn_opt_arg.flags & (HL_SYNC_HERE|HL_SYNC_THERE)) curwin->w_s->b_syn_sync_flags |= SF_MATCH; #ifdef FEAT_FOLDING *************** *** 4959,4966 **** #endif redraw_curbuf_later(SOME_VALID); ! syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */ ! return; /* don't free the progs and patterns now */ } } --- 4957,4964 ---- #endif redraw_curbuf_later(SOME_VALID); ! syn_stack_free_all(curwin->w_s); // Need to recompute all syntax. ! return; // don't free the progs and patterns now } } *************** *** 4984,4994 **** static void syn_cmd_region( exarg_T *eap, ! int syncing) /* TRUE for ":syntax sync region .." */ { char_u *arg = eap->arg; char_u *group_name_end; ! char_u *rest; /* next arg, NULL on error */ char_u *key_end; char_u *key = NULL; char_u *p; --- 4982,4992 ---- static void syn_cmd_region( exarg_T *eap, ! int syncing) // TRUE for ":syntax sync region .." { char_u *arg = eap->arg; char_u *group_name_end; ! char_u *rest; // next arg, NULL on error char_u *key_end; char_u *key = NULL; char_u *p; *************** *** 4999,5022 **** #define ITEM_MATCHGROUP 3 struct pat_ptr { ! synpat_T *pp_synp; /* pointer to syn_pattern */ ! int pp_matchgroup_id; /* matchgroup ID */ ! struct pat_ptr *pp_next; /* pointer to next pat_ptr */ } *(pat_ptrs[3]); ! /* patterns found in the line */ struct pat_ptr *ppp; struct pat_ptr *ppp_next; ! int pat_count = 0; /* nr of syn_patterns found */ int syn_id; int matchgroup_id = 0; ! int not_enough = FALSE; /* not enough arguments */ ! int illegal = FALSE; /* illegal arguments */ int success = FALSE; int idx; syn_opt_arg_T syn_opt_arg; int conceal_char = NUL; ! /* Isolate the group name, check for validity */ rest = get_group_name(arg, &group_name_end); pat_ptrs[0] = NULL; --- 4997,5020 ---- #define ITEM_MATCHGROUP 3 struct pat_ptr { ! synpat_T *pp_synp; // pointer to syn_pattern ! int pp_matchgroup_id; // matchgroup ID ! struct pat_ptr *pp_next; // pointer to next pat_ptr } *(pat_ptrs[3]); ! // patterns found in the line struct pat_ptr *ppp; struct pat_ptr *ppp_next; ! int pat_count = 0; // nr of syn_patterns found int syn_id; int matchgroup_id = 0; ! int not_enough = FALSE; // not enough arguments ! int illegal = FALSE; // illegal arguments int success = FALSE; int idx; syn_opt_arg_T syn_opt_arg; int conceal_char = NUL; ! // Isolate the group name, check for validity rest = get_group_name(arg, &group_name_end); pat_ptrs[0] = NULL; *************** *** 5038,5055 **** */ while (rest != NULL && !ends_excmd(*rest)) { ! /* Check for option arguments */ rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip); if (rest == NULL || ends_excmd(*rest)) break; ! /* must be a pattern or matchgroup then */ key_end = rest; while (*key_end && !VIM_ISWHITE(*key_end) && *key_end != '=') ++key_end; vim_free(key); key = vim_strnsave_up(rest, (int)(key_end - rest)); ! if (key == NULL) /* out of memory */ { rest = NULL; break; --- 5036,5053 ---- */ while (rest != NULL && !ends_excmd(*rest)) { ! // Check for option arguments rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip); if (rest == NULL || ends_excmd(*rest)) break; ! // must be a pattern or matchgroup then key_end = rest; while (*key_end && !VIM_ISWHITE(*key_end) && *key_end != '=') ++key_end; vim_free(key); key = vim_strnsave_up(rest, (int)(key_end - rest)); ! if (key == NULL) // out of memory { rest = NULL; break; *************** *** 5062,5068 **** item = ITEM_END; else if (STRCMP(key, "SKIP") == 0) { ! if (pat_ptrs[ITEM_SKIP] != NULL) /* one skip pattern allowed */ { illegal = TRUE; break; --- 5060,5066 ---- item = ITEM_END; else if (STRCMP(key, "SKIP") == 0) { ! if (pat_ptrs[ITEM_SKIP] != NULL) // one skip pattern allowed { illegal = TRUE; break; *************** *** 5126,5132 **** /* * Get the syntax pattern and the following offset(s). */ ! /* Enable the appropriate \z specials. */ if (item == ITEM_START) reg_do_extmatch = REX_SET; else if (item == ITEM_SKIP || item == ITEM_END) --- 5124,5130 ---- /* * Get the syntax pattern and the following offset(s). */ ! // Enable the appropriate \z specials. if (item == ITEM_START) reg_do_extmatch = REX_SET; else if (item == ITEM_SKIP || item == ITEM_END) *************** *** 5211,5218 **** } redraw_curbuf_later(SOME_VALID); ! syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */ ! success = TRUE; /* don't free the progs and patterns now */ } } --- 5209,5216 ---- } redraw_curbuf_later(SOME_VALID); ! syn_stack_free_all(curwin->w_s); // Need to recompute all syntax. ! success = TRUE; // don't free the progs and patterns now } } *************** *** 5390,5396 **** int i; char_u *name_u; ! /* Avoid using stricmp() too much, it's slow on some systems */ name_u = vim_strsave_up(name); if (name_u == NULL) return 0; --- 5388,5394 ---- int i; char_u *name_u; ! // Avoid using stricmp() too much, it's slow on some systems name_u = vim_strsave_up(name); if (name_u == NULL) return 0; *************** *** 5437,5443 **** return 0; id = syn_scl_name2id(name); ! if (id == 0) /* doesn't exist yet */ id = syn_add_cluster(name); else vim_free(name); --- 5435,5441 ---- return 0; id = syn_scl_name2id(name); ! if (id == 0) // doesn't exist yet id = syn_add_cluster(name); else vim_free(name); *************** *** 5563,5569 **** if (got_clstr) { redraw_curbuf_later(SOME_VALID); ! syn_stack_free_all(curwin->w_s); /* Need to recompute all. */ } } --- 5561,5567 ---- if (got_clstr) { redraw_curbuf_later(SOME_VALID); ! syn_stack_free_all(curwin->w_s); // Need to recompute all. } } *************** *** 5596,5616 **** int idx; char_u *cpo_save; ! /* need at least three chars */ if (arg == NULL || arg[0] == NUL || arg[1] == NUL || arg[2] == NUL) return NULL; end = skip_regexp(arg + 1, *arg, TRUE, NULL); ! if (*end != *arg) /* end delimiter not found */ { semsg(_("E401: Pattern delimiter not found: %s"), arg); return NULL; } ! /* store the pattern and compiled regexp program */ if ((ci->sp_pattern = vim_strnsave(arg + 1, (int)(end - arg - 1))) == NULL) return NULL; ! /* Make 'cpoptions' empty, to avoid the 'l' flag */ cpo_save = p_cpo; p_cpo = (char_u *)""; ci->sp_prog = vim_regcomp(ci->sp_pattern, RE_MAGIC); --- 5594,5614 ---- int idx; char_u *cpo_save; ! // need at least three chars if (arg == NULL || arg[0] == NUL || arg[1] == NUL || arg[2] == NUL) return NULL; end = skip_regexp(arg + 1, *arg, TRUE, NULL); ! if (*end != *arg) // end delimiter not found { semsg(_("E401: Pattern delimiter not found: %s"), arg); return NULL; } ! // store the pattern and compiled regexp program if ((ci->sp_pattern = vim_strnsave(arg + 1, (int)(end - arg - 1))) == NULL) return NULL; ! // Make 'cpoptions' empty, to avoid the 'l' flag cpo_save = p_cpo; p_cpo = (char_u *)""; ci->sp_prog = vim_regcomp(ci->sp_pattern, RE_MAGIC); *************** *** 5646,5675 **** if (idx >= 0) { ci->sp_off_flags |= (1 << idx); ! if (idx == SPO_LC_OFF) /* lc=99 */ { end += 3; *p = getdigits(&end); ! /* "lc=" offset automatically sets "ms=" offset */ if (!(ci->sp_off_flags & (1 << SPO_MS_OFF))) { ci->sp_off_flags |= (1 << SPO_MS_OFF); ci->sp_offsets[SPO_MS_OFF] = *p; } } ! else /* yy=x+99 */ { end += 4; if (*end == '+') { ++end; ! *p = getdigits(&end); /* positive offset */ } else if (*end == '-') { ++end; ! *p = -getdigits(&end); /* negative offset */ } } if (*end != ',') --- 5644,5673 ---- if (idx >= 0) { ci->sp_off_flags |= (1 << idx); ! if (idx == SPO_LC_OFF) // lc=99 { end += 3; *p = getdigits(&end); ! // "lc=" offset automatically sets "ms=" offset if (!(ci->sp_off_flags & (1 << SPO_MS_OFF))) { ci->sp_off_flags |= (1 << SPO_MS_OFF); ci->sp_offsets[SPO_MS_OFF] = *p; } } ! else // yy=x+99 { end += 4; if (*end == '+') { ++end; ! *p = getdigits(&end); // positive offset } else if (*end == '-') { ++end; ! *p = -getdigits(&end); // negative offset } } if (*end != ',') *************** *** 5766,5772 **** } else if (STRCMP(key, "LINECONT") == 0) { ! if (*next_arg == NUL) /* missing pattern */ { illegal = TRUE; break; --- 5764,5770 ---- } else if (STRCMP(key, "LINECONT") == 0) { ! if (*next_arg == NUL) // missing pattern { illegal = TRUE; break; *************** *** 5778,5784 **** break; } arg_end = skip_regexp(next_arg + 1, *next_arg, TRUE, NULL); ! if (*arg_end != *next_arg) /* end delimiter not found */ { illegal = TRUE; break; --- 5776,5782 ---- break; } arg_end = skip_regexp(next_arg + 1, *next_arg, TRUE, NULL); ! if (*arg_end != *next_arg) // end delimiter not found { illegal = TRUE; break; *************** *** 5786,5792 **** if (!eap->skip) { ! /* store the pattern and compiled regexp program */ if ((curwin->w_s->b_syn_linecont_pat = vim_strnsave(next_arg + 1, (int)(arg_end - next_arg - 1))) == NULL) { --- 5784,5790 ---- if (!eap->skip) { ! // store the pattern and compiled regexp program if ((curwin->w_s->b_syn_linecont_pat = vim_strnsave(next_arg + 1, (int)(arg_end - next_arg - 1))) == NULL) { *************** *** 5795,5801 **** } curwin->w_s->b_syn_linecont_ic = curwin->w_s->b_syn_ic; ! /* Make 'cpoptions' empty, to avoid the 'l' flag */ cpo_save = p_cpo; p_cpo = (char_u *)""; curwin->w_s->b_syn_linecont_prog = --- 5793,5799 ---- } curwin->w_s->b_syn_linecont_ic = curwin->w_s->b_syn_ic; ! // Make 'cpoptions' empty, to avoid the 'l' flag cpo_save = p_cpo; p_cpo = (char_u *)""; curwin->w_s->b_syn_linecont_prog = *************** *** 5837,5843 **** { eap->nextcmd = check_nextcmd(arg_start); redraw_curbuf_later(SOME_VALID); ! syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */ } } --- 5835,5841 ---- { eap->nextcmd = check_nextcmd(arg_start); redraw_curbuf_later(SOME_VALID); ! syn_stack_free_all(curwin->w_s); // Need to recompute all syntax. } } *************** *** 5851,5859 **** static int get_id_list( char_u **arg, ! int keylen, /* length of keyword */ ! short **list, /* where to store the resulting list, if not ! NULL, the list is silently skipped! */ int skip) { char_u *p = NULL; --- 5849,5857 ---- static int get_id_list( char_u **arg, ! int keylen, // length of keyword ! short **list, // where to store the resulting list, if not ! // NULL, the list is silently skipped! int skip) { char_u *p = NULL; *************** *** 5901,5907 **** { for (end = p; *end && !VIM_ISWHITE(*end) && *end != ','; ++end) ; ! name = alloc(end - p + 3); /* leave room for "^$" */ if (name == NULL) { failed = TRUE; --- 5899,5905 ---- { for (end = p; *end && !VIM_ISWHITE(*end) && *end != ','; ++end) ; ! name = alloc(end - p + 3); // leave room for "^$" if (name == NULL) { failed = TRUE; *************** *** 5974,5983 **** { if (round == 2) { ! /* Got more items than expected; can happen ! * when adding items that match: ! * "contains=a.*b,axb". ! * Go back to first round */ if (count >= total_count) { vim_free(retval); --- 5972,5981 ---- { if (round == 2) { ! // Got more items than expected; can happen ! // when adding items that match: ! // "contains=a.*b,axb". ! // Go back to first round if (count >= total_count) { vim_free(retval); *************** *** 5987,5993 **** retval[count] = i + 1; } ++count; ! id = -1; /* remember that we found one */ } } vim_regfree(regmatch.regprog); --- 5985,5991 ---- retval[count] = i + 1; } ++count; ! id = -1; // remember that we found one } } vim_regfree(regmatch.regprog); *************** *** 6004,6010 **** { if (round == 2) { ! /* Got more items than expected, go back to first round */ if (count >= total_count) { vim_free(retval); --- 6002,6008 ---- { if (round == 2) { ! // Got more items than expected, go back to first round if (count >= total_count) { vim_free(retval); *************** *** 6018,6024 **** p = skipwhite(end); if (*p != ',') break; ! p = skipwhite(p + 1); /* skip comma in between arguments */ } if (failed) break; --- 6016,6022 ---- p = skipwhite(end); if (*p != ',') break; ! p = skipwhite(p + 1); // skip comma in between arguments } if (failed) break; *************** *** 6027,6033 **** retval = ALLOC_MULT(short, count + 1); if (retval == NULL) break; ! retval[count] = 0; /* zero means end of the list */ total_count = count; } } --- 6025,6031 ---- retval = ALLOC_MULT(short, count + 1); if (retval == NULL) break; ! retval[count] = 0; // zero means end of the list total_count = count; } } *************** *** 6042,6048 **** if (*list == NULL) *list = retval; else ! vim_free(retval); /* list already found, don't overwrite it */ return OK; } --- 6040,6046 ---- if (*list == NULL) *list = retval; else ! vim_free(retval); // list already found, don't overwrite it return OK; } *************** *** 6079,6088 **** */ static int in_id_list( ! stateitem_T *cur_si, /* current item or NULL */ ! short *list, /* id list */ ! struct sp_syn *ssp, /* group id and ":syn include" tag of group */ ! int contained) /* group id is contained */ { int retval; short *scl_list; --- 6077,6086 ---- */ static int in_id_list( ! stateitem_T *cur_si, // current item or NULL ! short *list, // id list ! struct sp_syn *ssp, // group id and ":syn include" tag of group ! int contained) // group id is contained { int retval; short *scl_list; *************** *** 6091,6106 **** static int depth = 0; int r; ! /* If ssp has a "containedin" list and "cur_si" is in it, return TRUE. */ if (cur_si != NULL && ssp->cont_in_list != NULL && !(cur_si->si_flags & HL_MATCH)) { ! /* Ignore transparent items without a contains argument. Double check ! * that we don't go back past the first one. */ while ((cur_si->si_flags & HL_TRANS_CONT) && cur_si > (stateitem_T *)(current_state.ga_data)) --cur_si; ! /* cur_si->si_idx is -1 for keywords, these never contain anything. */ if (cur_si->si_idx >= 0 && in_id_list(NULL, ssp->cont_in_list, &(SYN_ITEMS(syn_block)[cur_si->si_idx].sp_syn), SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags & HL_CONTAINED)) --- 6089,6104 ---- static int depth = 0; int r; ! // If ssp has a "containedin" list and "cur_si" is in it, return TRUE. if (cur_si != NULL && ssp->cont_in_list != NULL && !(cur_si->si_flags & HL_MATCH)) { ! // Ignore transparent items without a contains argument. Double check ! // that we don't go back past the first one. while ((cur_si->si_flags & HL_TRANS_CONT) && cur_si > (stateitem_T *)(current_state.ga_data)) --cur_si; ! // cur_si->si_idx is -1 for keywords, these never contain anything. if (cur_si->si_idx >= 0 && in_id_list(NULL, ssp->cont_in_list, &(SYN_ITEMS(syn_block)[cur_si->si_idx].sp_syn), SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags & HL_CONTAINED)) *************** *** 6127,6145 **** { if (item < SYNID_TOP) { ! /* ALL or ALLBUT: accept all groups in the same file */ if (item - SYNID_ALLBUT != ssp->inc_tag) return FALSE; } else if (item < SYNID_CONTAINED) { ! /* TOP: accept all not-contained groups in the same file */ if (item - SYNID_TOP != ssp->inc_tag || contained) return FALSE; } else { ! /* CONTAINED: accept all contained groups in the same file */ if (item - SYNID_CONTAINED != ssp->inc_tag || !contained) return FALSE; } --- 6125,6143 ---- { if (item < SYNID_TOP) { ! // ALL or ALLBUT: accept all groups in the same file if (item - SYNID_ALLBUT != ssp->inc_tag) return FALSE; } else if (item < SYNID_CONTAINED) { ! // TOP: accept all not-contained groups in the same file if (item - SYNID_TOP != ssp->inc_tag || contained) return FALSE; } else { ! // CONTAINED: accept all contained groups in the same file if (item - SYNID_CONTAINED != ssp->inc_tag || !contained) return FALSE; } *************** *** 6159,6166 **** if (item >= SYNID_CLUSTER) { scl_list = SYN_CLSTR(syn_block)[item - SYNID_CLUSTER].scl_list; ! /* restrict recursiveness to 30 to avoid an endless loop for a ! * cluster that includes itself (indirectly) */ if (scl_list != NULL && depth < 30) { ++depth; --- 6157,6164 ---- if (item >= SYNID_CLUSTER) { scl_list = SYN_CLSTR(syn_block)[item - SYNID_CLUSTER].scl_list; ! // restrict recursiveness to 30 to avoid an endless loop for a ! // cluster that includes itself (indirectly) if (scl_list != NULL && depth < 30) { ++depth; *************** *** 6177,6184 **** struct subcommand { ! char *name; /* subcommand name */ ! void (*func)(exarg_T *, int); /* function to call */ }; static struct subcommand subcommands[] = --- 6175,6182 ---- struct subcommand { ! char *name; // subcommand name ! void (*func)(exarg_T *, int); // function to call }; static struct subcommand subcommands[] = *************** *** 6219,6231 **** syn_cmdlinep = eap->cmdlinep; ! /* isolate subcommand name */ for (subcmd_end = arg; ASCII_ISALPHA(*subcmd_end); ++subcmd_end) ; subcmd_name = vim_strnsave(arg, (int)(subcmd_end - arg)); if (subcmd_name != NULL) { ! if (eap->skip) /* skip error messages for all subcommands */ ++emsg_skip; for (i = 0; ; ++i) { --- 6217,6229 ---- syn_cmdlinep = eap->cmdlinep; ! // isolate subcommand name for (subcmd_end = arg; ASCII_ISALPHA(*subcmd_end); ++subcmd_end) ; subcmd_name = vim_strnsave(arg, (int)(subcmd_end - arg)); if (subcmd_name != NULL) { ! if (eap->skip) // skip error messages for all subcommands ++emsg_skip; for (i = 0; ; ++i) { *************** *** 6260,6267 **** hash_init(&curwin->w_s->b_keywtab); hash_init(&curwin->w_s->b_keywtab_ic); #ifdef FEAT_SPELL ! /* TODO: keep the spell checking as it was. */ ! curwin->w_p_spell = FALSE; /* No spell checking */ clear_string_option(&curwin->w_s->b_p_spc); clear_string_option(&curwin->w_s->b_p_spf); clear_string_option(&curwin->w_s->b_p_spl); --- 6258,6265 ---- hash_init(&curwin->w_s->b_keywtab); hash_init(&curwin->w_s->b_keywtab_ic); #ifdef FEAT_SPELL ! // TODO: keep the spell checking as it was. ! curwin->w_p_spell = FALSE; // No spell checking clear_string_option(&curwin->w_s->b_p_spc); clear_string_option(&curwin->w_s->b_p_spf); clear_string_option(&curwin->w_s->b_p_spl); *************** *** 6269,6289 **** clear_string_option(&curwin->w_s->b_syn_isk); } ! /* save value of b:current_syntax */ old_value = get_var_value((char_u *)"b:current_syntax"); if (old_value != NULL) old_value = vim_strsave(old_value); ! /* Apply the "syntax" autocommand event, this finds and loads the syntax ! * file. */ apply_autocmds(EVENT_SYNTAX, eap->arg, curbuf->b_fname, TRUE, curbuf); ! /* move value of b:current_syntax to w:current_syntax */ new_value = get_var_value((char_u *)"b:current_syntax"); if (new_value != NULL) set_internal_string_var((char_u *)"w:current_syntax", new_value); ! /* restore value of b:current_syntax */ if (old_value == NULL) do_unlet((char_u *)"b:current_syntax", TRUE); else --- 6267,6287 ---- clear_string_option(&curwin->w_s->b_syn_isk); } ! // save value of b:current_syntax old_value = get_var_value((char_u *)"b:current_syntax"); if (old_value != NULL) old_value = vim_strsave(old_value); ! // Apply the "syntax" autocommand event, this finds and loads the syntax ! // file. apply_autocmds(EVENT_SYNTAX, eap->arg, curbuf->b_fname, TRUE, curbuf); ! // move value of b:current_syntax to w:current_syntax new_value = get_var_value((char_u *)"b:current_syntax"); if (new_value != NULL) set_internal_string_var((char_u *)"w:current_syntax", new_value); ! // restore value of b:current_syntax if (old_value == NULL) do_unlet((char_u *)"b:current_syntax", TRUE); else *************** *** 6305,6314 **** static enum { ! EXP_SUBCMD, /* expand ":syn" sub-commands */ ! EXP_CASE, /* expand ":syn case" arguments */ ! EXP_SPELL, /* expand ":syn spell" arguments */ ! EXP_SYNC /* expand ":syn sync" arguments */ } expand_what; /* --- 6303,6312 ---- static enum { ! EXP_SUBCMD, // expand ":syn" sub-commands ! EXP_CASE, // expand ":syn case" arguments ! EXP_SPELL, // expand ":syn spell" arguments ! EXP_SYNC // expand ":syn sync" arguments } expand_what; /* *************** *** 6341,6358 **** { char_u *p; ! /* Default: expand subcommands */ xp->xp_context = EXPAND_SYNTAX; expand_what = EXP_SUBCMD; xp->xp_pattern = arg; include_link = 0; include_default = 0; ! /* (part of) subcommand already typed */ if (*arg != NUL) { p = skiptowhite(arg); ! if (*p != NUL) /* past first word */ { xp->xp_pattern = skipwhite(p); if (*skiptowhite(xp->xp_pattern) != NUL) --- 6339,6356 ---- { char_u *p; ! // Default: expand subcommands xp->xp_context = EXPAND_SYNTAX; expand_what = EXP_SUBCMD; xp->xp_pattern = arg; include_link = 0; include_default = 0; ! // (part of) subcommand already typed if (*arg != NUL) { p = skiptowhite(arg); ! if (*p != NUL) // past first word { xp->xp_pattern = skipwhite(p); if (*skiptowhite(xp->xp_pattern) != NUL) *************** *** 6417,6428 **** win_T *wp, long lnum, colnr_T col, ! int trans, /* remove transparency */ ! int *spellp, /* return: can do spell checking */ ! int keep_state) /* keep state of char at "col" */ { ! /* When the position is not after the current position and in the same ! * line of the same buffer, need to restart parsing. */ if (wp->w_buffer != syn_buf || lnum != current_lnum || col < current_col) --- 6415,6426 ---- win_T *wp, long lnum, colnr_T col, ! int trans, // remove transparency ! int *spellp, // return: can do spell checking ! int keep_state) // keep state of char at "col" { ! // When the position is not after the current position and in the same ! // line of the same buffer, need to restart parsing. if (wp->w_buffer != syn_buf || lnum != current_lnum || col < current_col) *************** *** 6430,6437 **** else if (wp->w_buffer == syn_buf && lnum == current_lnum && col > current_col) ! /* next_match may not be correct when moving around, e.g. with the ! * "skip" expression in searchpair() */ next_match_idx = -1; (void)get_syntax_attr(col, spellp, keep_state); --- 6428,6435 ---- else if (wp->w_buffer == syn_buf && lnum == current_lnum && col > current_col) ! // next_match may not be correct when moving around, e.g. with the ! // "skip" expression in searchpair() next_match_idx = -1; (void)get_syntax_attr(col, spellp, keep_state); *************** *** 6474,6481 **** { if (i >= current_state.ga_len) { ! /* Need to invalidate the state, because we didn't properly finish it ! * for the last character, "keep_state" was TRUE. */ invalidate_current_state(); current_col = MAXCOL; return -1; --- 6472,6479 ---- { if (i >= current_state.ga_len) { ! // Need to invalidate the state, because we didn't properly finish it ! // for the last character, "keep_state" was TRUE. invalidate_current_state(); current_col = MAXCOL; return -1; *************** *** 6494,6500 **** int level = 0; int i; ! /* Return quickly when there are no fold items at all. */ if (wp->w_s->b_syn_folditems != 0 && !wp->w_s->b_syn_error # ifdef SYN_TIME_LIMIT --- 6492,6498 ---- int level = 0; int i; ! // Return quickly when there are no fold items at all. if (wp->w_s->b_syn_folditems != 0 && !wp->w_s->b_syn_error # ifdef SYN_TIME_LIMIT *************** *** 6652,6659 **** } } ! /* Sort on total time. Skip if there are no items to avoid passing NULL ! * pointer to qsort(). */ if (ga.ga_len > 1) qsort(ga.ga_data, (size_t)ga.ga_len, sizeof(time_entry_T), syn_compare_syntime); --- 6650,6657 ---- } } ! // Sort on total time. Skip if there are no items to avoid passing NULL ! // pointer to qsort(). if (ga.ga_len > 1) qsort(ga.ga_data, (size_t)ga.ga_len, sizeof(time_entry_T), syn_compare_syntime); *************** *** 6665,6671 **** p = ((time_entry_T *)ga.ga_data) + idx; msg_puts(profile_msg(&p->total)); ! msg_puts(" "); /* make sure there is always a separating space */ msg_advance(13); msg_outnum(p->count); msg_puts(" "); --- 6663,6669 ---- p = ((time_entry_T *)ga.ga_data) + idx; msg_puts(profile_msg(&p->total)); ! msg_puts(" "); // make sure there is always a separating space msg_advance(13); msg_outnum(p->count); msg_puts(" "); *************** *** 6686,6692 **** msg_advance(69); if (Columns < 80) ! len = 20; /* will wrap anyway */ else len = Columns - 70; if (len > (int)STRLEN(p->pattern)) --- 6684,6690 ---- msg_advance(69); if (Columns < 80) ! len = 20; // will wrap anyway else len = Columns - 70; if (len > (int)STRLEN(p->pattern)) *************** *** 6706,6709 **** } #endif ! #endif /* FEAT_SYN_HL */ --- 6704,6707 ---- } #endif ! #endif // FEAT_SYN_HL *** ../vim-8.1.2394/src/tag.c 2019-11-30 22:47:42.655331183 +0100 --- src/tag.c 2019-12-05 21:25:49.816393204 +0100 *************** *** 45,64 **** * At the end, all the matches from ga_match[] are concatenated, to make a list * sorted on priority. */ ! #define MT_ST_CUR 0 /* static match in current file */ ! #define MT_GL_CUR 1 /* global match in current file */ ! #define MT_GL_OTH 2 /* global match in other file */ ! #define MT_ST_OTH 3 /* static match in other file */ ! #define MT_IC_OFF 4 /* add for icase match */ ! #define MT_RE_OFF 8 /* add for regexp match */ ! #define MT_MASK 7 /* mask for printing priority */ #define MT_COUNT 16 static char *mt_names[MT_COUNT/2] = {"FSC", "F C", "F ", "FS ", " SC", " C", " ", " S "}; ! #define NOTAGFILE 99 /* return value for jumpto_tag */ ! static char_u *nofile_fname = NULL; /* fname for NOTAGFILE error */ static void taglen_advance(int l); --- 45,64 ---- * At the end, all the matches from ga_match[] are concatenated, to make a list * sorted on priority. */ ! #define MT_ST_CUR 0 // static match in current file ! #define MT_GL_CUR 1 // global match in current file ! #define MT_GL_OTH 2 // global match in other file ! #define MT_ST_OTH 3 // static match in other file ! #define MT_IC_OFF 4 // add for icase match ! #define MT_RE_OFF 8 // add for regexp match ! #define MT_MASK 7 // mask for printing priority #define MT_COUNT 16 static char *mt_names[MT_COUNT/2] = {"FSC", "F C", "F ", "FS ", " SC", " C", " ", " S "}; ! #define NOTAGFILE 99 // return value for jumpto_tag ! static char_u *nofile_fname = NULL; // fname for NOTAGFILE error static void taglen_advance(int l); *************** *** 91,97 **** static char_u *tfu_inv_ret_msg = (char_u *)N_("E987: invalid return value from tagfunc"); #endif ! static char_u *tagmatchname = NULL; /* name of last used tag */ #if defined(FEAT_QUICKFIX) /* --- 91,97 ---- static char_u *tfu_inv_ret_msg = (char_u *)N_("E987: invalid return value from tagfunc"); #endif ! static char_u *tagmatchname = NULL; // name of last used tag #if defined(FEAT_QUICKFIX) /* *************** *** 130,140 **** */ int do_tag( ! char_u *tag, /* tag (pattern) to jump to */ int type, int count, ! int forceit, /* :ta with ! */ ! int verbose) /* print "tag not found" message */ { taggy_T *tagstack = curwin->w_tagstack; int tagstackidx = curwin->w_tagstackidx; --- 130,140 ---- */ int do_tag( ! char_u *tag, // tag (pattern) to jump to int type, int count, ! int forceit, // :ta with ! ! int verbose) // print "tag not found" message { taggy_T *tagstack = curwin->w_tagstack; int tagstackidx = curwin->w_tagstackidx; *************** *** 158,170 **** char_u **new_matches; int use_tagstack; int skip_msg = FALSE; ! char_u *buf_ffname = curbuf->b_ffname; /* name to use for ! priority computation */ int use_tfu = 1; ! /* remember the matches for the last used tag */ static int num_matches = 0; ! static int max_num_matches = 0; /* limit used for match search */ static char_u **matches = NULL; static int flags; --- 158,170 ---- char_u **new_matches; int use_tagstack; int skip_msg = FALSE; ! char_u *buf_ffname = curbuf->b_ffname; // name to use for ! // priority computation int use_tfu = 1; ! // remember the matches for the last used tag static int num_matches = 0; ! static int max_num_matches = 0; // limit used for match search static char_u **matches = NULL; static int flags; *************** *** 179,185 **** #ifdef EXITFREE if (type == DT_FREE) { ! /* remove the list of matches */ FreeWild(num_matches, matches); # ifdef FEAT_CSCOPE cs_free_tags(); --- 179,185 ---- #ifdef EXITFREE if (type == DT_FREE) { ! // remove the list of matches FreeWild(num_matches, matches); # ifdef FEAT_CSCOPE cs_free_tags(); *************** *** 200,206 **** free_string_option(nofile_fname); nofile_fname = NULL; ! CLEAR_POS(&saved_fmark.mark); /* shutup gcc 4.0 */ saved_fmark.fnum = 0; /* --- 200,206 ---- free_string_option(nofile_fname); nofile_fname = NULL; ! CLEAR_POS(&saved_fmark.mark); // shutup gcc 4.0 saved_fmark.fnum = 0; /* *************** *** 228,234 **** #endif use_tagstack = TRUE; ! /* new pattern, add to the tag stack */ if (*tag != NUL && (type == DT_TAG || type == DT_SELECT || type == DT_JUMP #ifdef FEAT_QUICKFIX --- 228,234 ---- #endif use_tagstack = TRUE; ! // new pattern, add to the tag stack if (*tag != NUL && (type == DT_TAG || type == DT_SELECT || type == DT_JUMP #ifdef FEAT_QUICKFIX *************** *** 245,252 **** if (ptag_entry.tagname != NULL && STRCMP(ptag_entry.tagname, tag) == 0) { ! /* Jumping to same tag: keep the current match, so that ! * the CursorHold autocommand example works. */ cur_match = ptag_entry.cur_match; cur_fnum = ptag_entry.cur_fnum; } --- 245,252 ---- if (ptag_entry.tagname != NULL && STRCMP(ptag_entry.tagname, tag) == 0) { ! // Jumping to same tag: keep the current match, so that ! // the CursorHold autocommand example works. cur_match = ptag_entry.cur_match; cur_fnum = ptag_entry.cur_fnum; } *************** *** 267,273 **** while (tagstackidx < tagstacklen) tagstack_clear_entry(&tagstack[--tagstacklen]); ! /* if the tagstack is full: remove oldest entry */ if (++tagstacklen > TAGSTACKSIZE) { tagstacklen = TAGSTACKSIZE; --- 267,273 ---- while (tagstackidx < tagstacklen) tagstack_clear_entry(&tagstack[--tagstacklen]); ! // if the tagstack is full: remove oldest entry if (++tagstacklen > TAGSTACKSIZE) { tagstacklen = TAGSTACKSIZE; *************** *** 287,293 **** } curwin->w_tagstacklen = tagstacklen; ! save_pos = TRUE; /* save the cursor position below */ } new_tag = TRUE; --- 287,293 ---- } curwin->w_tagstacklen = tagstacklen; ! save_pos = TRUE; // save the cursor position below } new_tag = TRUE; *************** *** 300,311 **** #endif tagstacklen == 0) { ! /* empty stack */ emsg(_(e_tagstack)); goto end_do_tag; } ! if (type == DT_POP) /* go to older position */ { #ifdef FEAT_FOLDING int old_KeyTyped = KeyTyped; --- 300,311 ---- #endif tagstacklen == 0) { ! // empty stack emsg(_(e_tagstack)); goto end_do_tag; } ! if (type == DT_POP) // go to older position { #ifdef FEAT_FOLDING int old_KeyTyped = KeyTyped; *************** *** 315,337 **** emsg(_(bottommsg)); if (tagstackidx + count == 0) { ! /* We did [num]^T from the bottom of the stack */ tagstackidx = 0; goto end_do_tag; } ! /* We weren't at the bottom of the stack, so jump all the ! * way to the bottom now. ! */ tagstackidx = 0; } ! else if (tagstackidx >= tagstacklen) /* count == 0? */ { emsg(_(topmsg)); goto end_do_tag; } ! /* Make a copy of the fmark, autocommands may invalidate the ! * tagstack before it's used. */ saved_fmark = tagstack[tagstackidx].fmark; if (saved_fmark.fnum != curbuf->b_fnum) { --- 315,336 ---- emsg(_(bottommsg)); if (tagstackidx + count == 0) { ! // We did [num]^T from the bottom of the stack tagstackidx = 0; goto end_do_tag; } ! // We weren't at the bottom of the stack, so jump all the ! // way to the bottom now. tagstackidx = 0; } ! else if (tagstackidx >= tagstacklen) // count == 0? { emsg(_(topmsg)); goto end_do_tag; } ! // Make a copy of the fmark, autocommands may invalidate the ! // tagstack before it's used. saved_fmark = tagstack[tagstackidx].fmark; if (saved_fmark.fnum != curbuf->b_fnum) { *************** *** 342,352 **** if (buflist_getfile(saved_fmark.fnum, saved_fmark.mark.lnum, GETF_SETMARK, forceit) == FAIL) { ! tagstackidx = oldtagstackidx; /* back to old posn */ goto end_do_tag; } ! /* An BufReadPost autocommand may jump to the '" mark, but ! * we don't what that here. */ curwin->w_cursor.lnum = saved_fmark.mark.lnum; } else --- 341,351 ---- if (buflist_getfile(saved_fmark.fnum, saved_fmark.mark.lnum, GETF_SETMARK, forceit) == FAIL) { ! tagstackidx = oldtagstackidx; // back to old posn goto end_do_tag; } ! // An BufReadPost autocommand may jump to the '" mark, but ! // we don't what that here. curwin->w_cursor.lnum = saved_fmark.mark.lnum; } else *************** *** 362,368 **** foldOpenCursor(); #endif ! /* remove the old list of matches */ FreeWild(num_matches, matches); #ifdef FEAT_CSCOPE cs_free_tags(); --- 361,367 ---- foldOpenCursor(); #endif ! // remove the old list of matches FreeWild(num_matches, matches); #ifdef FEAT_CSCOPE cs_free_tags(); *************** *** 387,394 **** else #endif { ! /* ":tag" (no argument): go to newer pattern */ ! save_pos = TRUE; /* save the cursor position below */ if ((tagstackidx += count - 1) >= tagstacklen) { /* --- 386,393 ---- else #endif { ! // ":tag" (no argument): go to newer pattern ! save_pos = TRUE; // save the cursor position below if ((tagstackidx += count - 1) >= tagstacklen) { /* *************** *** 400,406 **** emsg(_(topmsg)); save_pos = FALSE; } ! else if (tagstackidx < 0) /* must have been count == 0 */ { emsg(_(bottommsg)); tagstackidx = 0; --- 399,405 ---- emsg(_(topmsg)); save_pos = FALSE; } ! else if (tagstackidx < 0) // must have been count == 0 { emsg(_(bottommsg)); tagstackidx = 0; *************** *** 411,419 **** } new_tag = TRUE; } ! else /* go to other matching tag */ { ! /* Save index for when selection is cancelled. */ prevtagstackidx = tagstackidx; #if defined(FEAT_QUICKFIX) --- 410,418 ---- } new_tag = TRUE; } ! else // go to other matching tag { ! // Save index for when selection is cancelled. prevtagstackidx = tagstackidx; #if defined(FEAT_QUICKFIX) *************** *** 476,484 **** tagstack[tagstackidx].fmark.fnum = curbuf->b_fnum; } ! /* Curwin will change in the call to jumpto_tag() if ":stag" was ! * used or an autocommand jumps to another window; store value of ! * tagstackidx now. */ curwin->w_tagstackidx = tagstackidx; if (type != DT_SELECT && type != DT_JUMP) { --- 475,483 ---- tagstack[tagstackidx].fmark.fnum = curbuf->b_fnum; } ! // Curwin will change in the call to jumpto_tag() if ":stag" was ! // used or an autocommand jumps to another window; store value of ! // tagstackidx now. curwin->w_tagstackidx = tagstackidx; if (type != DT_SELECT && type != DT_JUMP) { *************** *** 488,496 **** } } ! /* When not using the current buffer get the name of buffer "cur_fnum". ! * Makes sure that the tag order doesn't change when using a remembered ! * position for "cur_match". */ if (cur_fnum != curbuf->b_fnum) { buf_T *buf = buflist_findnr(cur_fnum); --- 487,495 ---- } } ! // When not using the current buffer get the name of buffer "cur_fnum". ! // Makes sure that the tag order doesn't change when using a remembered ! // position for "cur_match". if (cur_fnum != curbuf->b_fnum) { buf_T *buf = buflist_findnr(cur_fnum); *************** *** 540,546 **** else max_num_matches = cur_match + 1; ! /* when the argument starts with '/', use it as a regexp */ if (!no_regexp && *name == '/') { flags = TAG_REGEXP; --- 539,545 ---- else max_num_matches = cur_match + 1; ! // when the argument starts with '/', use it as a regexp if (!no_regexp && *name == '/') { flags = TAG_REGEXP; *************** *** 562,581 **** if (find_tags(name, &new_num_matches, &new_matches, flags, max_num_matches, buf_ffname) == OK && new_num_matches < max_num_matches) ! max_num_matches = MAXCOL; /* If less than max_num_matches ! found: all matches found. */ ! /* If there already were some matches for the same name, move them ! * to the start. Avoids that the order changes when using ! * ":tnext" and jumping to another file. */ if (!new_tag && !other_name) { int j, k; int idx = 0; tagptrs_T tagp, tagp2; ! /* Find the position of each old match in the new list. Need ! * to use parse_match() to find the tag line. */ for (j = 0; j < num_matches; ++j) { parse_match(matches[j], &tagp); --- 561,580 ---- if (find_tags(name, &new_num_matches, &new_matches, flags, max_num_matches, buf_ffname) == OK && new_num_matches < max_num_matches) ! max_num_matches = MAXCOL; // If less than max_num_matches ! // found: all matches found. ! // If there already were some matches for the same name, move them ! // to the start. Avoids that the order changes when using ! // ":tnext" and jumping to another file. if (!new_tag && !other_name) { int j, k; int idx = 0; tagptrs_T tagp, tagp2; ! // Find the position of each old match in the new list. Need ! // to use parse_match() to find the tag line. for (j = 0; j < num_matches; ++j) { parse_match(matches[j], &tagp); *************** *** 632,638 **** { if (add_llist_tags(tag, num_matches, matches) == FAIL) goto end_do_tag; ! cur_match = 0; /* Jump to the first tag */ } #endif --- 631,637 ---- { if (add_llist_tags(tag, num_matches, matches) == FAIL) goto end_do_tag; ! cur_match = 0; // Jump to the first tag } #endif *************** *** 644,650 **** i = prompt_for_number(NULL); if (i <= 0 || i > num_matches || got_int) { ! /* no valid choice: don't change anything */ if (use_tagstack) { tagstack[tagstackidx].fmark = saved_fmark; --- 643,649 ---- i = prompt_for_number(NULL); if (i <= 0 || i > num_matches || got_int) { ! // no valid choice: don't change anything if (use_tagstack) { tagstack[tagstackidx].fmark = saved_fmark; *************** *** 661,669 **** if (cur_match >= num_matches) { ! /* Avoid giving this error when a file wasn't found and we're ! * looking for a match in another file, which wasn't found. ! * There will be an emsg("file doesn't exist") below then. */ if ((type == DT_NEXT || type == DT_FIRST) && nofile_fname == NULL) { --- 660,668 ---- if (cur_match >= num_matches) { ! // Avoid giving this error when a file wasn't found and we're ! // looking for a match in another file, which wasn't found. ! // There will be an emsg("file doesn't exist") below then. if ((type == DT_NEXT || type == DT_FIRST) && nofile_fname == NULL) { *************** *** 717,723 **** && (num_matches > 1 || ic) && !skip_msg) { ! /* Give an indication of the number of matching tags */ sprintf((char *)IObuff, _("tag %d of %d%s"), cur_match + 1, num_matches, --- 716,722 ---- && (num_matches > 1 || ic) && !skip_msg) { ! // Give an indication of the number of matching tags sprintf((char *)IObuff, _("tag %d of %d%s"), cur_match + 1, num_matches, *************** *** 731,737 **** msg_attr((char *)IObuff, HL_ATTR(HLF_W)); else msg((char *)IObuff); ! msg_scroll = TRUE; /* don't overwrite this message */ } else give_warning(IObuff, ic); --- 730,736 ---- msg_attr((char *)IObuff, HL_ATTR(HLF_W)); else msg((char *)IObuff); ! msg_scroll = TRUE; // don't overwrite this message } else give_warning(IObuff, ic); *************** *** 743,749 **** } #if defined(FEAT_EVAL) ! /* Let the SwapExists event know what tag we are jumping to. */ vim_snprintf((char *)IObuff, IOSIZE, ":ta %s\r", name); set_vim_var_string(VV_SWAPCOMMAND, IObuff, -1); #endif --- 742,748 ---- } #if defined(FEAT_EVAL) ! // Let the SwapExists event know what tag we are jumping to. vim_snprintf((char *)IObuff, IOSIZE, ":ta %s\r", name); set_vim_var_string(VV_SWAPCOMMAND, IObuff, -1); #endif *************** *** 759,765 **** if (i == NOTAGFILE) { ! /* File not found: try again with another matching tag */ if ((type == DT_PREV && cur_match > 0) || ((type == DT_TAG || type == DT_NEXT || type == DT_FIRST) --- 758,764 ---- if (i == NOTAGFILE) { ! // File not found: try again with another matching tag if ((type == DT_PREV && cur_match > 0) || ((type == DT_TAG || type == DT_NEXT || type == DT_FIRST) *************** *** 782,789 **** } else { ! /* We may have jumped to another window, check that ! * tagstackidx is still valid. */ if (use_tagstack && tagstackidx > curwin->w_tagstacklen) tagstackidx = curwin->w_tagstackidx; #ifdef FEAT_CSCOPE --- 781,788 ---- } else { ! // We may have jumped to another window, check that ! // tagstackidx is still valid. if (use_tagstack && tagstackidx > curwin->w_tagstacklen) tagstackidx = curwin->w_tagstackidx; #ifdef FEAT_CSCOPE *************** *** 795,806 **** } end_do_tag: ! /* Only store the new index when using the tagstack and it's valid. */ if (use_tagstack && tagstackidx <= curwin->w_tagstacklen) curwin->w_tagstackidx = tagstackidx; ! postponed_split = 0; /* don't split next time */ # ifdef FEAT_QUICKFIX ! g_do_tagpreview = 0; /* don't do tag preview next time */ # endif #ifdef FEAT_CSCOPE --- 794,805 ---- } end_do_tag: ! // Only store the new index when using the tagstack and it's valid. if (use_tagstack && tagstackidx <= curwin->w_tagstacklen) curwin->w_tagstackidx = tagstackidx; ! postponed_split = 0; // don't split next time # ifdef FEAT_QUICKFIX ! g_do_tagpreview = 0; // don't do tag preview next time # endif #ifdef FEAT_CSCOPE *************** *** 1041,1047 **** parse_match(matches[i], &tagp); ! /* Save the tag name */ len = (int)(tagp.tagname_end - tagp.tagname); if (len > 128) len = 128; --- 1040,1046 ---- parse_match(matches[i], &tagp); ! // Save the tag name len = (int)(tagp.tagname_end - tagp.tagname); if (len > 128) len = 128; *************** *** 1185,1198 **** int tagstackidx = curwin->w_tagstackidx; int tagstacklen = curwin->w_tagstacklen; ! /* Highlight title */ msg_puts_title(_("\n # TO tag FROM line in file/text")); for (i = 0; i < tagstacklen; ++i) { if (tagstack[i].tagname != NULL) { name = fm_getname(&(tagstack[i].fmark), 30); ! if (name == NULL) /* file name not available */ continue; msg_putchar('\n'); --- 1184,1197 ---- int tagstackidx = curwin->w_tagstackidx; int tagstacklen = curwin->w_tagstacklen; ! // Highlight title msg_puts_title(_("\n # TO tag FROM line in file/text")); for (i = 0; i < tagstacklen; ++i) { if (tagstack[i].tagname != NULL) { name = fm_getname(&(tagstack[i].fmark), 30); ! if (name == NULL) // file name not available continue; msg_putchar('\n'); *************** *** 1207,1215 **** ? HL_ATTR(HLF_D) : 0); vim_free(name); } ! out_flush(); /* show one line at a time */ } ! if (tagstackidx == tagstacklen) /* idx at top of stack */ msg_puts("\n>"); } --- 1206,1214 ---- ? HL_ATTR(HLF_D) : 0); vim_free(name); } ! out_flush(); // show one line at a time } ! if (tagstackidx == tagstacklen) // idx at top of stack msg_puts("\n>"); } *************** *** 1228,1241 **** { i = (int)TOUPPER_ASC(*s1) - (int)TOUPPER_ASC(*s2); if (i != 0) ! return i; /* this character different */ if (*s1 == NUL) ! break; /* strings match until NUL */ ++s1; ++s2; --len; } ! return 0; /* strings match */ } #endif --- 1227,1240 ---- { i = (int)TOUPPER_ASC(*s1) - (int)TOUPPER_ASC(*s2); if (i != 0) ! return i; // this character different if (*s1 == NUL) ! break; // strings match until NUL ++s1; ++s2; --len; } ! return 0; // strings match } #endif *************** *** 1244,1254 **** */ typedef struct { ! char_u *pat; /* the pattern */ ! int len; /* length of pat[] */ ! char_u *head; /* start of pattern head */ ! int headlen; /* length of head[] */ ! regmatch_T regmatch; /* regexp program, may be NULL */ } pat_T; /* --- 1243,1253 ---- */ typedef struct { ! char_u *pat; // the pattern ! int len; // length of pat[] ! char_u *head; // start of pattern head ! int headlen; // length of head[] ! regmatch_T regmatch; // regexp program, may be NULL } pat_T; /* *************** *** 1261,1268 **** pats->headlen = pats->len; if (has_re) { ! /* When the pattern starts with '^' or "\\<", binary searching can be ! * used (much faster). */ if (pats->pat[0] == '^') pats->head = pats->pat + 1; else if (pats->pat[0] == '\\' && pats->pat[1] == '<') --- 1260,1267 ---- pats->headlen = pats->len; if (has_re) { ! // When the pattern starts with '^' or "\\<", binary searching can be ! // used (much faster). if (pats->pat[0] == '^') pats->head = pats->pat + 1; else if (pats->pat[0] == '\\' && pats->pat[1] == '<') *************** *** 1275,1281 **** if (vim_strchr((char_u *)(p_magic ? ".[~*\\$" : "\\$"), pats->head[pats->headlen]) != NULL) break; ! if (p_tl != 0 && pats->headlen > p_tl) /* adjust for 'taglength' */ pats->headlen = p_tl; } --- 1274,1280 ---- if (vim_strchr((char_u *)(p_magic ? ".[~*\\$" : "\\$"), pats->head[pats->headlen]) != NULL) break; ! if (p_tl != 0 && pats->headlen > p_tl) // adjust for 'taglength' pats->headlen = p_tl; } *************** *** 1545,1587 **** */ int find_tags( ! char_u *pat, /* pattern to search for */ ! int *num_matches, /* return: number of matches found */ ! char_u ***matchesp, /* return: array of matches found */ int flags, ! int mincount, /* MAXCOL: find all matches ! other: minimal number of matches */ ! char_u *buf_ffname) /* name of buffer for priority */ { FILE *fp; ! char_u *lbuf; /* line buffer */ ! int lbuf_size = LSIZE; /* length of lbuf */ ! char_u *tag_fname; /* name of tag file */ ! tagname_T tn; /* info for get_tagfname() */ ! int first_file; /* trying first tag file */ tagptrs_T tagp; ! int did_open = FALSE; /* did open a tag file */ ! int stop_searching = FALSE; /* stop when match found or error */ ! int retval = FAIL; /* return value */ ! int is_static; /* current tag line is static */ ! int is_current; /* file name matches */ ! int eof = FALSE; /* found end-of-file */ char_u *p; char_u *s; int i; #ifdef FEAT_TAG_BINS ! int tag_file_sorted = NUL; /* !_TAG_FILE_SORTED value */ ! struct tag_search_info /* Binary search file offsets */ { ! off_T low_offset; /* offset for first char of first line that ! could match */ ! off_T high_offset; /* offset of char after last line that could ! match */ ! off_T curr_offset; /* Current file offset in search range */ ! off_T curr_offset_used; /* curr_offset used when skipping back */ ! off_T match_offset; /* Where the binary search found a tag */ ! int low_char; /* first char at low_offset */ ! int high_char; /* first char at high_offset */ } search_info; off_T filesize; int tagcmp; --- 1544,1586 ---- */ int find_tags( ! char_u *pat, // pattern to search for ! int *num_matches, // return: number of matches found ! char_u ***matchesp, // return: array of matches found int flags, ! int mincount, // MAXCOL: find all matches ! // other: minimal number of matches ! char_u *buf_ffname) // name of buffer for priority { FILE *fp; ! char_u *lbuf; // line buffer ! int lbuf_size = LSIZE; // length of lbuf ! char_u *tag_fname; // name of tag file ! tagname_T tn; // info for get_tagfname() ! int first_file; // trying first tag file tagptrs_T tagp; ! int did_open = FALSE; // did open a tag file ! int stop_searching = FALSE; // stop when match found or error ! int retval = FAIL; // return value ! int is_static; // current tag line is static ! int is_current; // file name matches ! int eof = FALSE; // found end-of-file char_u *p; char_u *s; int i; #ifdef FEAT_TAG_BINS ! int tag_file_sorted = NUL; // !_TAG_FILE_SORTED value ! struct tag_search_info // Binary search file offsets { ! off_T low_offset; // offset for first char of first line that ! // could match ! off_T high_offset; // offset of char after last line that could ! // match ! off_T curr_offset; // Current file offset in search range ! off_T curr_offset_used; // curr_offset used when skipping back ! off_T match_offset; // Where the binary search found a tag ! int low_char; // first char at low_offset ! int high_char; // first char at high_offset } search_info; off_T filesize; int tagcmp; *************** *** 1590,1608 **** #endif enum { ! TS_START, /* at start of file */ ! TS_LINEAR /* linear searching forward, till EOF */ #ifdef FEAT_TAG_BINS ! , TS_BINARY, /* binary searching */ ! TS_SKIP_BACK, /* skipping backwards */ ! TS_STEP_FORWARD /* stepping forwards */ #endif ! } state; /* Current search state */ int cmplen; ! int match; /* matches */ ! int match_no_ic = 0;/* matches with rm_ic == FALSE */ ! int match_re; /* match with regexp */ int matchoff = 0; int save_emsg_off; --- 1589,1607 ---- #endif enum { ! TS_START, // at start of file ! TS_LINEAR // linear searching forward, till EOF #ifdef FEAT_TAG_BINS ! , TS_BINARY, // binary searching ! TS_SKIP_BACK, // skipping backwards ! TS_STEP_FORWARD // stepping forwards #endif ! } state; // Current search state int cmplen; ! int match; // matches ! int match_no_ic = 0;// matches with rm_ic == FALSE ! int match_re; // match with regexp int matchoff = 0; int save_emsg_off; *************** *** 1618,1656 **** char_u *etag_fname; } incstack[INCSTACK_SIZE]; ! int incstack_idx = 0; /* index in incstack */ ! char_u *ebuf; /* additional buffer for etag fname */ ! int is_etag; /* current file is emaces style */ #endif char_u *mfp; ! garray_T ga_match[MT_COUNT]; /* stores matches in sequence */ ! hashtab_T ht_match[MT_COUNT]; /* stores matches by key */ hash_T hash = 0; ! int match_count = 0; /* number of matches found */ char_u **matches; int mtt; int help_save; #ifdef FEAT_MULTI_LANG int help_pri = 0; ! char_u *help_lang_find = NULL; /* lang to be found */ ! char_u help_lang[3]; /* lang of current tags file */ ! char_u *saved_pat = NULL; /* copy of pat[] */ ! int is_txt = FALSE; /* flag of file extension */ #endif ! pat_T orgpat; /* holds unconverted pattern info */ vimconv_T vimconv; #ifdef FEAT_TAG_BINS int findall = (mincount == MAXCOL || mincount == TAG_MANY); ! /* find all matching tags */ ! int sort_error = FALSE; /* tags file not sorted */ ! int linear; /* do a linear search */ ! int sortic = FALSE; /* tag file sorted in nocase */ #endif ! int line_error = FALSE; /* syntax error */ ! int has_re = (flags & TAG_REGEXP); /* regexp used */ int help_only = (flags & TAG_HELP); int name_only = (flags & TAG_NAMES); int noic = (flags & TAG_NOIC); --- 1617,1655 ---- char_u *etag_fname; } incstack[INCSTACK_SIZE]; ! int incstack_idx = 0; // index in incstack ! char_u *ebuf; // additional buffer for etag fname ! int is_etag; // current file is emaces style #endif char_u *mfp; ! garray_T ga_match[MT_COUNT]; // stores matches in sequence ! hashtab_T ht_match[MT_COUNT]; // stores matches by key hash_T hash = 0; ! int match_count = 0; // number of matches found char_u **matches; int mtt; int help_save; #ifdef FEAT_MULTI_LANG int help_pri = 0; ! char_u *help_lang_find = NULL; // lang to be found ! char_u help_lang[3]; // lang of current tags file ! char_u *saved_pat = NULL; // copy of pat[] ! int is_txt = FALSE; // flag of file extension #endif ! pat_T orgpat; // holds unconverted pattern info vimconv_T vimconv; #ifdef FEAT_TAG_BINS int findall = (mincount == MAXCOL || mincount == TAG_MANY); ! // find all matching tags ! int sort_error = FALSE; // tags file not sorted ! int linear; // do a linear search ! int sortic = FALSE; // tag file sorted in nocase #endif ! int line_error = FALSE; // syntax error ! int has_re = (flags & TAG_REGEXP); // regexp used int help_only = (flags & TAG_HELP); int name_only = (flags & TAG_NAMES); int noic = (flags & TAG_NOIC); *************** *** 1695,1701 **** hash_init(&ht_match[mtt]); } ! /* check for out of memory situation */ if (lbuf == NULL || tag_fname == NULL #ifdef FEAT_EMACS_TAGS || ebuf == NULL --- 1694,1700 ---- hash_init(&ht_match[mtt]); } ! // check for out of memory situation if (lbuf == NULL || tag_fname == NULL #ifdef FEAT_EMACS_TAGS || ebuf == NULL *************** *** 1704,1721 **** goto findtag_end; #ifdef FEAT_CSCOPE ! STRCPY(tag_fname, "from cscope"); /* for error messages */ #endif /* * Initialize a few variables */ ! if (help_only) /* want tags from help file */ ! curbuf->b_help = TRUE; /* will be restored later */ #ifdef FEAT_CSCOPE else if (use_cscope) { ! /* Make sure we don't mix help and cscope, confuses Coverity. */ help_only = FALSE; curbuf->b_help = FALSE; } --- 1703,1720 ---- goto findtag_end; #ifdef FEAT_CSCOPE ! STRCPY(tag_fname, "from cscope"); // for error messages #endif /* * Initialize a few variables */ ! if (help_only) // want tags from help file ! curbuf->b_help = TRUE; // will be restored later #ifdef FEAT_CSCOPE else if (use_cscope) { ! // Make sure we don't mix help and cscope, confuses Coverity. help_only = FALSE; curbuf->b_help = FALSE; } *************** *** 1725,1732 **** #ifdef FEAT_MULTI_LANG if (curbuf->b_help) { ! /* When "@ab" is specified use only the "ab" language, otherwise ! * search all languages. */ if (orgpat.len > 3 && pat[orgpat.len - 3] == '@' && ASCII_ISALPHA(pat[orgpat.len - 2]) && ASCII_ISALPHA(pat[orgpat.len - 1])) --- 1724,1731 ---- #ifdef FEAT_MULTI_LANG if (curbuf->b_help) { ! // When "@ab" is specified use only the "ab" language, otherwise ! // search all languages. if (orgpat.len > 3 && pat[orgpat.len - 3] == '@' && ASCII_ISALPHA(pat[orgpat.len - 2]) && ASCII_ISALPHA(pat[orgpat.len - 1])) *************** *** 1741,1759 **** } } #endif ! if (p_tl != 0 && orgpat.len > p_tl) /* adjust for 'taglength' */ orgpat.len = p_tl; save_emsg_off = emsg_off; ! emsg_off = TRUE; /* don't want error for invalid RE here */ prepare_pats(&orgpat, has_re); emsg_off = save_emsg_off; if (has_re && orgpat.regmatch.regprog == NULL) goto findtag_end; #ifdef FEAT_TAG_BINS ! /* This is only to avoid a compiler warning for using search_info ! * uninitialised. */ vim_memset(&search_info, 0, (size_t)1); #endif --- 1740,1758 ---- } } #endif ! if (p_tl != 0 && orgpat.len > p_tl) // adjust for 'taglength' orgpat.len = p_tl; save_emsg_off = emsg_off; ! emsg_off = TRUE; // don't want error for invalid RE here prepare_pats(&orgpat, has_re); emsg_off = save_emsg_off; if (has_re && orgpat.regmatch.regprog == NULL) goto findtag_end; #ifdef FEAT_TAG_BINS ! // This is only to avoid a compiler warning for using search_info ! // uninitialised. vim_memset(&search_info, 0, (size_t)1); #endif *************** *** 1780,1786 **** * Only ignore case when TAG_NOIC not used or 'ignorecase' set. */ #ifdef FEAT_MULTI_LANG ! /* Set a flag if the file extension is .txt */ if ((flags & TAG_KEEP_LANG) && help_lang_find == NULL && curbuf->b_fname != NULL --- 1779,1785 ---- * Only ignore case when TAG_NOIC not used or 'ignorecase' set. */ #ifdef FEAT_MULTI_LANG ! // Set a flag if the file extension is .txt if ((flags & TAG_KEEP_LANG) && help_lang_find == NULL && curbuf->b_fname != NULL *************** *** 1814,1847 **** */ #ifdef FEAT_CSCOPE if (use_cscope) ! fp = NULL; /* avoid GCC warning */ else #endif { #ifdef FEAT_MULTI_LANG if (curbuf->b_help) { ! /* Keep en if the file extension is .txt*/ if (is_txt) STRCPY(help_lang, "en"); else { ! /* Prefer help tags according to 'helplang'. Put the ! * two-letter language name in help_lang[]. */ i = (int)STRLEN(tag_fname); if (i > 3 && tag_fname[i - 3] == '-') STRCPY(help_lang, tag_fname + i - 2); else STRCPY(help_lang, "en"); } ! /* When searching for a specific language skip tags files ! * for other languages. */ if (help_lang_find != NULL && STRICMP(help_lang, help_lang_find) != 0) continue; ! /* For CTRL-] in a help file prefer a match with the same ! * language. */ if ((flags & TAG_KEEP_LANG) && help_lang_find == NULL && curbuf->b_fname != NULL --- 1813,1846 ---- */ #ifdef FEAT_CSCOPE if (use_cscope) ! fp = NULL; // avoid GCC warning else #endif { #ifdef FEAT_MULTI_LANG if (curbuf->b_help) { ! // Keep en if the file extension is .txt if (is_txt) STRCPY(help_lang, "en"); else { ! // Prefer help tags according to 'helplang'. Put the ! // two-letter language name in help_lang[]. i = (int)STRLEN(tag_fname); if (i > 3 && tag_fname[i - 3] == '-') STRCPY(help_lang, tag_fname + i - 2); else STRCPY(help_lang, "en"); } ! // When searching for a specific language skip tags files ! // for other languages. if (help_lang_find != NULL && STRICMP(help_lang, help_lang_find) != 0) continue; ! // For CTRL-] in a help file prefer a match with the same ! // language. if ((flags & TAG_KEEP_LANG) && help_lang_find == NULL && curbuf->b_fname != NULL *************** *** 1863,1870 **** } if (s == NULL || *s == NUL) { ! /* Language not in 'helplang': use last, prefer English, ! * unless found already. */ ++help_pri; if (STRICMP(help_lang, "en") != 0) ++help_pri; --- 1862,1869 ---- } if (s == NULL || *s == NUL) { ! // Language not in 'helplang': use last, prefer English, ! // unless found already. ++help_pri; if (STRICMP(help_lang, "en") != 0) ++help_pri; *************** *** 1883,1893 **** verbose_leave(); } } ! did_open = TRUE; /* remember that we found at least one file */ ! state = TS_START; /* we're at the start of the file */ #ifdef FEAT_EMACS_TAGS ! is_etag = 0; /* default is: not emacs style */ #endif /* --- 1882,1892 ---- verbose_leave(); } } ! did_open = TRUE; // remember that we found at least one file ! state = TS_START; // we're at the start of the file #ifdef FEAT_EMACS_TAGS ! is_etag = 0; // default is: not emacs style #endif /* *************** *** 1896,1916 **** for (;;) { #ifdef FEAT_TAG_BINS ! /* check for CTRL-C typed, more often when jumping around */ if (state == TS_BINARY || state == TS_SKIP_BACK) line_breakcheck(); else #endif fast_breakcheck(); ! if ((flags & TAG_INS_COMP)) /* Double brackets for gcc */ ins_compl_check_keys(30, FALSE); if (got_int || ins_compl_interrupted()) { stop_searching = TRUE; break; } ! /* When mincount is TAG_MANY, stop when enough matches have been ! * found (for completion). */ if (mincount == TAG_MANY && match_count >= TAG_MANY) { stop_searching = TRUE; --- 1895,1915 ---- for (;;) { #ifdef FEAT_TAG_BINS ! // check for CTRL-C typed, more often when jumping around if (state == TS_BINARY || state == TS_SKIP_BACK) line_breakcheck(); else #endif fast_breakcheck(); ! if ((flags & TAG_INS_COMP)) // Double brackets for gcc ins_compl_check_keys(30, FALSE); if (got_int || ins_compl_interrupted()) { stop_searching = TRUE; break; } ! // When mincount is TAG_MANY, stop when enough matches have been ! // found (for completion). if (mincount == TAG_MANY && match_count >= TAG_MANY) { stop_searching = TRUE; *************** *** 1928,1934 **** offset = search_info.low_offset + ((search_info.high_offset - search_info.low_offset) / 2); if (offset == search_info.curr_offset) ! break; /* End the binary search without a match. */ else search_info.curr_offset = offset; } --- 1927,1933 ---- offset = search_info.low_offset + ((search_info.high_offset - search_info.low_offset) / 2); if (offset == search_info.curr_offset) ! break; // End the binary search without a match. else search_info.curr_offset = offset; } *************** *** 1953,1976 **** */ if (state == TS_BINARY || state == TS_SKIP_BACK) { ! /* Adjust the search file offset to the correct position */ search_info.curr_offset_used = search_info.curr_offset; vim_fseek(fp, search_info.curr_offset, SEEK_SET); eof = vim_fgets(lbuf, lbuf_size, fp); if (!eof && search_info.curr_offset != 0) { ! /* The explicit cast is to work around a bug in gcc 3.4.2 ! * (repeated below). */ search_info.curr_offset = vim_ftell(fp); if (search_info.curr_offset == search_info.high_offset) { ! /* oops, gone a bit too far; try from low offset */ vim_fseek(fp, search_info.low_offset, SEEK_SET); search_info.curr_offset = search_info.low_offset; } eof = vim_fgets(lbuf, lbuf_size, fp); } ! /* skip empty and blank lines */ while (!eof && vim_isblankline(lbuf)) { search_info.curr_offset = vim_ftell(fp); --- 1952,1975 ---- */ if (state == TS_BINARY || state == TS_SKIP_BACK) { ! // Adjust the search file offset to the correct position search_info.curr_offset_used = search_info.curr_offset; vim_fseek(fp, search_info.curr_offset, SEEK_SET); eof = vim_fgets(lbuf, lbuf_size, fp); if (!eof && search_info.curr_offset != 0) { ! // The explicit cast is to work around a bug in gcc 3.4.2 ! // (repeated below). search_info.curr_offset = vim_ftell(fp); if (search_info.curr_offset == search_info.high_offset) { ! // oops, gone a bit too far; try from low offset vim_fseek(fp, search_info.low_offset, SEEK_SET); search_info.curr_offset = search_info.low_offset; } eof = vim_fgets(lbuf, lbuf_size, fp); } ! // skip empty and blank lines while (!eof && vim_isblankline(lbuf)) { search_info.curr_offset = vim_ftell(fp); *************** *** 1978,1984 **** } if (eof) { ! /* Hit end of file. Skip backwards. */ state = TS_SKIP_BACK; search_info.match_offset = vim_ftell(fp); search_info.curr_offset = search_info.curr_offset_used; --- 1977,1983 ---- } if (eof) { ! // Hit end of file. Skip backwards. state = TS_SKIP_BACK; search_info.match_offset = vim_ftell(fp); search_info.curr_offset = search_info.curr_offset_used; *************** *** 1992,1998 **** else #endif { ! /* skip empty and blank lines */ do { #ifdef FEAT_CSCOPE --- 1991,1997 ---- else #endif { ! // skip empty and blank lines do { #ifdef FEAT_CSCOPE *************** *** 2006,2024 **** if (eof) { #ifdef FEAT_EMACS_TAGS ! if (incstack_idx) /* this was an included file */ { --incstack_idx; ! fclose(fp); /* end of this file ... */ fp = incstack[incstack_idx].fp; STRCPY(tag_fname, incstack[incstack_idx].etag_fname); vim_free(incstack[incstack_idx].etag_fname); ! is_etag = 1; /* (only etags can include) */ ! continue; /* ... continue with parent file */ } else #endif ! break; /* end of file */ } } line_read_in: --- 2005,2023 ---- if (eof) { #ifdef FEAT_EMACS_TAGS ! if (incstack_idx) // this was an included file { --incstack_idx; ! fclose(fp); // end of this file ... fp = incstack[incstack_idx].fp; STRCPY(tag_fname, incstack[incstack_idx].etag_fname); vim_free(incstack[incstack_idx].etag_fname); ! is_etag = 1; // (only etags can include) ! continue; // ... continue with parent file } else #endif ! break; // end of file } } line_read_in: *************** *** 2028,2040 **** char_u *conv_line; int len; ! /* Convert every line. Converting the pattern from 'enc' to ! * the tags file encoding doesn't work, because characters are ! * not recognized. */ conv_line = string_convert(&vimconv, lbuf, NULL); if (conv_line != NULL) { ! /* Copy or swap lbuf and conv_line. */ len = (int)STRLEN(conv_line) + 1; if (len > lbuf_size) { --- 2027,2039 ---- char_u *conv_line; int len; ! // Convert every line. Converting the pattern from 'enc' to ! // the tags file encoding doesn't work, because characters are ! // not recognized. conv_line = string_convert(&vimconv, lbuf, NULL); if (conv_line != NULL) { ! // Copy or swap lbuf and conv_line. len = (int)STRLEN(conv_line) + 1; if (len > lbuf_size) { *************** *** 2063,2069 **** # endif ) { ! is_etag = 1; /* in case at the start */ state = TS_LINEAR; if (!vim_fgets(ebuf, LSIZE, fp)) { --- 2062,2068 ---- # endif ) { ! is_etag = 1; // in case at the start state = TS_LINEAR; if (!vim_fgets(ebuf, LSIZE, fp)) { *************** *** 2078,2084 **** if (STRNCMP(p + 1, "include", 7) == 0 && incstack_idx < INCSTACK_SIZE) { ! /* Save current "fp" and "tag_fname" in the stack. */ if ((incstack[incstack_idx].etag_fname = vim_strsave(tag_fname)) != NULL) { --- 2077,2083 ---- if (STRNCMP(p + 1, "include", 7) == 0 && incstack_idx < INCSTACK_SIZE) { ! // Save current "fp" and "tag_fname" in the stack. if ((incstack[incstack_idx].etag_fname = vim_strsave(tag_fname)) != NULL) { *************** *** 2087,2094 **** incstack[incstack_idx].fp = fp; fp = NULL; ! /* Figure out "tag_fname" and "fp" to use for ! * included file. */ fullpath_ebuf = expand_tag_fname(ebuf, tag_fname, FALSE); if (fullpath_ebuf != NULL) --- 2086,2093 ---- incstack[incstack_idx].fp = fp; fp = NULL; ! // Figure out "tag_fname" and "fp" to use for ! // included file. fullpath_ebuf = expand_tag_fname(ebuf, tag_fname, FALSE); if (fullpath_ebuf != NULL) *************** *** 2101,2114 **** vim_strncpy(tag_fname, fullpath_ebuf, MAXPATHL); ++incstack_idx; ! is_etag = 0; /* we can include anything */ } vim_free(fullpath_ebuf); } if (fp == NULL) { ! /* Can't open the included file, skip it and ! * restore old value of "fp". */ fp = incstack[incstack_idx].fp; vim_free(incstack[incstack_idx].etag_fname); } --- 2100,2113 ---- vim_strncpy(tag_fname, fullpath_ebuf, MAXPATHL); ++incstack_idx; ! is_etag = 0; // we can include anything } vim_free(fullpath_ebuf); } if (fp == NULL) { ! // Can't open the included file, skip it and ! // restore old value of "fp". fp = incstack[incstack_idx].fp; vim_free(incstack[incstack_idx].etag_fname); } *************** *** 2125,2138 **** */ if (state == TS_START) { ! /* The header ends when the line sorts below "!_TAG_". When ! * case is folded lower case letters sort before "_". */ if (STRNCMP(lbuf, "!_TAG_", 6) <= 0 || (lbuf[0] == '!' && ASCII_ISLOWER(lbuf[1]))) { if (STRNCMP(lbuf, "!_TAG_", 6) != 0) ! /* Non-header item before the header, e.g. "!" itself. ! */ goto parse_line; /* --- 2124,2136 ---- */ if (state == TS_START) { ! // The header ends when the line sorts below "!_TAG_". When ! // case is folded lower case letters sort before "_". if (STRNCMP(lbuf, "!_TAG_", 6) <= 0 || (lbuf[0] == '!' && ASCII_ISLOWER(lbuf[1]))) { if (STRNCMP(lbuf, "!_TAG_", 6) != 0) ! // Non-header item before the header, e.g. "!" itself. goto parse_line; /* *************** *** 2144,2162 **** #endif if (STRNCMP(lbuf, "!_TAG_FILE_ENCODING\t", 20) == 0) { ! /* Prepare to convert every line from the specified ! * encoding to 'encoding'. */ for (p = lbuf + 20; *p > ' ' && *p < 127; ++p) ; *p = NUL; convert_setup(&vimconv, lbuf + 20, p_enc); } ! /* Read the next line. Unrecognized flags are ignored. */ continue; } ! /* Headers ends. */ #ifdef FEAT_TAG_BINS /* --- 2142,2160 ---- #endif if (STRNCMP(lbuf, "!_TAG_FILE_ENCODING\t", 20) == 0) { ! // Prepare to convert every line from the specified ! // encoding to 'encoding'. for (p = lbuf + 20; *p > ' ' && *p < 127; ++p) ; *p = NUL; convert_setup(&vimconv, lbuf + 20, p_enc); } ! // Read the next line. Unrecognized flags are ignored. continue; } ! // Headers ends. #ifdef FEAT_TAG_BINS /* *************** *** 2189,2196 **** if (state == TS_BINARY && orgpat.regmatch.rm_ic && !sortic) { ! /* Binary search won't work for ignoring case, use linear ! * search. */ linear = TRUE; state = TS_LINEAR; } --- 2187,2194 ---- if (state == TS_BINARY && orgpat.regmatch.rm_ic && !sortic) { ! // Binary search won't work for ignoring case, use linear ! // search. linear = TRUE; state = TS_LINEAR; } *************** *** 2267,2273 **** tagp.tagname_end = vim_strchr(lbuf, TAB); if (tagp.tagname_end == NULL) { ! /* Corrupted tag line. */ line_error = TRUE; break; } --- 2265,2271 ---- tagp.tagname_end = vim_strchr(lbuf, TAB); if (tagp.tagname_end == NULL) { ! // Corrupted tag line. line_error = TRUE; break; } *************** *** 2277,2283 **** * there is no regexp, or the tag is too short. */ cmplen = (int)(tagp.tagname_end - tagp.tagname); ! if (p_tl != 0 && cmplen > p_tl) /* adjust for 'taglength' */ cmplen = p_tl; if (has_re && orgpat.headlen < cmplen) cmplen = orgpat.headlen; --- 2275,2281 ---- * there is no regexp, or the tag is too short. */ cmplen = (int)(tagp.tagname_end - tagp.tagname); ! if (p_tl != 0 && cmplen > p_tl) // adjust for 'taglength' cmplen = p_tl; if (has_re && orgpat.headlen < cmplen) cmplen = orgpat.headlen; *************** *** 2319,2327 **** if (tagcmp == 0) { ! /* We've located the tag, now skip back and search ! * forward until the first matching tag is found. ! */ state = TS_SKIP_BACK; search_info.match_offset = search_info.curr_offset; continue; --- 2317,2324 ---- if (tagcmp == 0) { ! // We've located the tag, now skip back and search ! // forward until the first matching tag is found. state = TS_SKIP_BACK; search_info.match_offset = search_info.curr_offset; continue; *************** *** 2352,2358 **** continue; } ! /* No match yet and are at the end of the binary search. */ break; } else if (state == TS_SKIP_BACK) --- 2349,2355 ---- continue; } ! // No match yet and are at the end of the binary search. break; } else if (state == TS_SKIP_BACK) *************** *** 2360,2367 **** if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0) state = TS_STEP_FORWARD; else ! /* Have to skip back more. Restore the curr_offset ! * used, otherwise we get stuck at a long line. */ search_info.curr_offset = search_info.curr_offset_used; continue; } --- 2357,2364 ---- if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0) state = TS_STEP_FORWARD; else ! // Have to skip back more. Restore the curr_offset ! // used, otherwise we get stuck at a long line. search_info.curr_offset = search_info.curr_offset_used; continue; } *************** *** 2370,2383 **** if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0) { if ((off_T)vim_ftell(fp) > search_info.match_offset) ! break; /* past last match */ else ! continue; /* before first match */ } } else #endif ! /* skip this match if it can't match */ if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0) continue; --- 2367,2380 ---- if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0) { if ((off_T)vim_ftell(fp) > search_info.match_offset) ! break; // past last match else ! continue; // before first match } } else #endif ! // skip this match if it can't match if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0) continue; *************** *** 2413,2421 **** * a regexp). */ cmplen = (int)(tagp.tagname_end - tagp.tagname); ! if (p_tl != 0 && cmplen > p_tl) /* adjust for 'taglength' */ cmplen = p_tl; ! /* if tag length does not match, don't try comparing */ if (orgpat.len != cmplen) match = FALSE; else --- 2410,2418 ---- * a regexp). */ cmplen = (int)(tagp.tagname_end - tagp.tagname); ! if (p_tl != 0 && cmplen > p_tl) // adjust for 'taglength' cmplen = p_tl; ! // if tag length does not match, don't try comparing if (orgpat.len != cmplen) match = FALSE; else *************** *** 2467,2479 **** #ifdef FEAT_CSCOPE if (use_cscope) { ! /* Don't change the ordering, always use the same table. */ mtt = MT_GL_OTH; } else #endif { ! /* Decide in which array to store this match. */ is_current = test_for_current( #ifdef FEAT_EMACS_TAGS is_etag, --- 2464,2476 ---- #ifdef FEAT_CSCOPE if (use_cscope) { ! // Don't change the ordering, always use the same table. mtt = MT_GL_OTH; } else #endif { ! // Decide in which array to store this match. is_current = test_for_current( #ifdef FEAT_EMACS_TAGS is_etag, *************** *** 2482,2493 **** buf_ffname); #ifdef FEAT_EMACS_TAGS is_static = FALSE; ! if (!is_etag) /* emacs tags are never static */ #endif is_static = test_for_static(&tagp); ! /* decide in which of the sixteen tables to store this ! * match */ if (is_static) { if (is_current) --- 2479,2490 ---- buf_ffname); #ifdef FEAT_EMACS_TAGS is_static = FALSE; ! if (!is_etag) // emacs tags are never static #endif is_static = test_for_static(&tagp); ! // decide in which of the sixteen tables to store this ! // match if (is_static) { if (is_current) *************** *** 2580,2586 **** if (mfp != NULL) vim_strncpy(mfp, tagp.tagname, len); ! /* if wanted, re-read line to get long form too */ if (State & INSERT) get_it_again = p_sft; } --- 2577,2583 ---- if (mfp != NULL) vim_strncpy(mfp, tagp.tagname, len); ! // if wanted, re-read line to get long form too if (State & INSERT) get_it_again = p_sft; } *************** *** 2592,2606 **** size_t ebuf_len = 0; #endif ! /* Save the tag in a buffer. ! * Use 0x02 to separate fields (Can't use NUL because the ! * hash key is terminated by NUL, or Ctrl_A because that is ! * part of some Emacs tag files -- see parse_tag_line). ! * Emacs tag: <0x02><0x02> ! * other tag: <0x02><0x02> ! * without Emacs tags: <0x02> ! * Here is the "mtt" value plus 1 to avoid NUL. ! */ len = (int)tag_fname_len + (int)STRLEN(lbuf) + 3; #ifdef FEAT_EMACS_TAGS if (is_etag) --- 2589,2602 ---- size_t ebuf_len = 0; #endif ! // Save the tag in a buffer. ! // Use 0x02 to separate fields (Can't use NUL because the ! // hash key is terminated by NUL, or Ctrl_A because that is ! // part of some Emacs tag files -- see parse_tag_line). ! // Emacs tag: <0x02><0x02> ! // other tag: <0x02><0x02> ! // without Emacs tags: <0x02> ! // Here is the "mtt" value plus 1 to avoid NUL. len = (int)tag_fname_len + (int)STRLEN(lbuf) + 3; #ifdef FEAT_EMACS_TAGS if (is_etag) *************** *** 2618,2625 **** p[0] = mtt + 1; STRCPY(p + 1, tag_fname); #ifdef BACKSLASH_IN_FILENAME ! /* Ignore differences in slashes, avoid adding ! * both path/file and path\file. */ slash_adjust(p + 1); #endif p[tag_fname_len + 1] = TAG_SEP; --- 2614,2621 ---- p[0] = mtt + 1; STRCPY(p + 1, tag_fname); #ifdef BACKSLASH_IN_FILENAME ! // Ignore differences in slashes, avoid adding ! // both path/file and path\file. slash_adjust(p + 1); #endif p[tag_fname_len + 1] = TAG_SEP; *************** *** 2663,2669 **** == FAIL || ga_grow(&ga_match[mtt], 1) != OK) { ! /* Out of memory! Just forget about the rest. */ retval = OK; stop_searching = TRUE; break; --- 2659,2665 ---- == FAIL || ga_grow(&ga_match[mtt], 1) != OK) { ! // Out of memory! Just forget about the rest. retval = OK; stop_searching = TRUE; break; *************** *** 2676,2682 **** } } else ! /* duplicate tag, drop it */ vim_free(mfp); } } --- 2672,2678 ---- } } else ! // duplicate tag, drop it vim_free(mfp); } } *************** *** 2684,2690 **** if (use_cscope && eof) break; #endif ! } /* forever */ if (line_error) { --- 2680,2686 ---- if (use_cscope && eof) break; #endif ! } // forever if (line_error) { *************** *** 2737,2743 **** #endif break; ! } /* end of for-each-file loop */ #ifdef FEAT_CSCOPE if (!use_cscope) --- 2733,2739 ---- #endif break; ! } // end of for-each-file loop #ifdef FEAT_CSCOPE if (!use_cscope) *************** *** 2745,2767 **** tagname_free(&tn); #ifdef FEAT_TAG_BINS ! /* stop searching when already did a linear search, or when TAG_NOIC ! * used, and 'ignorecase' not set or already did case-ignore search */ if (stop_searching || linear || (!p_ic && noic) || orgpat.regmatch.rm_ic) break; # ifdef FEAT_CSCOPE if (use_cscope) break; # endif ! orgpat.regmatch.rm_ic = TRUE; /* try another time while ignoring case */ } #endif if (!stop_searching) { ! if (!did_open && verbose) /* never opened any tags file */ emsg(_("E433: No tags file")); ! retval = OK; /* It's OK even when no tag found */ } findtag_end: --- 2741,2763 ---- tagname_free(&tn); #ifdef FEAT_TAG_BINS ! // stop searching when already did a linear search, or when TAG_NOIC ! // used, and 'ignorecase' not set or already did case-ignore search if (stop_searching || linear || (!p_ic && noic) || orgpat.regmatch.rm_ic) break; # ifdef FEAT_CSCOPE if (use_cscope) break; # endif ! orgpat.regmatch.rm_ic = TRUE; // try another time while ignoring case } #endif if (!stop_searching) { ! if (!did_open && verbose) // never opened any tags file emsg(_("E433: No tags file")); ! retval = OK; // It's OK even when no tag found } findtag_end: *************** *** 2795,2804 **** { if (!name_only) { ! /* Change mtt back to zero-based. */ *mfp = *mfp - 1; ! /* change the TAG_SEP back to NUL */ for (p = mfp + 1; *p != NUL; ++p) if (*p == TAG_SEP) *p = NUL; --- 2791,2800 ---- { if (!name_only) { ! // Change mtt back to zero-based. *mfp = *mfp - 1; ! // change the TAG_SEP back to NUL for (p = mfp + 1; *p != NUL; ++p) if (*p == TAG_SEP) *p = NUL; *************** *** 2868,2876 **** */ int get_tagfname( ! tagname_T *tnp, /* holds status info */ ! int first, /* TRUE when first file name is wanted */ ! char_u *buf) /* pointer to buffer of MAXPATHL chars */ { char_u *fname = NULL; char_u *r_ptr; --- 2864,2872 ---- */ int get_tagfname( ! tagname_T *tnp, // holds status info ! int first, // TRUE when first file name is wanted ! char_u *buf) // pointer to buffer of MAXPATHL chars { char_u *fname = NULL; char_u *r_ptr; *************** *** 2893,2902 **** do_in_runtimepath((char_u *) #ifdef FEAT_MULTI_LANG # ifdef VMS ! /* Functions decc$to_vms() and decc$translate_vms() crash ! * on some VMS systems with wildcards "??". Seems ECO ! * patches do fix the problem in C RTL, but we can't use ! * an #ifdef for that. */ "doc/tags doc/tags-*" # else "doc/tags doc/tags-??" --- 2889,2898 ---- do_in_runtimepath((char_u *) #ifdef FEAT_MULTI_LANG # ifdef VMS ! // Functions decc$to_vms() and decc$translate_vms() crash ! // on some VMS systems with wildcards "??". Seems ECO ! // patches do fix the problem in C RTL, but we can't use ! // an #ifdef for that. "doc/tags doc/tags-*" # else "doc/tags doc/tags-??" *************** *** 2909,2916 **** if (tnp->tn_hf_idx >= tag_fnames.ga_len) { ! /* Not found in 'runtimepath', use 'helpfile', if it exists and ! * wasn't used yet, replacing "help.txt" with "tags". */ if (tnp->tn_hf_idx > tag_fnames.ga_len || *p_hf == NUL) return FAIL; ++tnp->tn_hf_idx; --- 2905,2912 ---- if (tnp->tn_hf_idx >= tag_fnames.ga_len) { ! // Not found in 'runtimepath', use 'helpfile', if it exists and ! // wasn't used yet, replacing "help.txt" with "tags". if (tnp->tn_hf_idx > tag_fnames.ga_len || *p_hf == NUL) return FAIL; ++tnp->tn_hf_idx; *************** *** 2933,2940 **** if (first) { ! /* Init. We make a copy of 'tags', because autocommands may change ! * the value without notifying us. */ tnp->tn_tags = vim_strsave((*curbuf->b_p_tags != NUL) ? curbuf->b_p_tags : p_tags); if (tnp->tn_tags == NULL) --- 2929,2936 ---- if (first) { ! // Init. We make a copy of 'tags', because autocommands may change ! // the value without notifying us. tnp->tn_tags = vim_strsave((*curbuf->b_p_tags != NUL) ? curbuf->b_p_tags : p_tags); if (tnp->tn_tags == NULL) *************** *** 2962,2968 **** { char_u *filename = NULL; ! /* Stop when used all parts of 'tags'. */ if (*tnp->tn_np == NUL) { vim_findfile_cleanup(tnp->tn_search_ctx); --- 2958,2964 ---- { char_u *filename = NULL; ! // Stop when used all parts of 'tags'. if (*tnp->tn_np == NUL) { vim_findfile_cleanup(tnp->tn_search_ctx); *************** *** 2981,2996 **** #else r_ptr = NULL; #endif ! /* move the filename one char forward and truncate the ! * filepath with a NUL */ filename = gettail(buf); STRMOVE(filename + 1, filename); *filename++ = NUL; tnp->tn_search_ctx = vim_findfile_init(buf, filename, r_ptr, 100, ! FALSE, /* don't free visited list */ ! FINDFILE_FILE, /* we search for a file */ tnp->tn_search_ctx, TRUE, curbuf->b_ffname); if (tnp->tn_search_ctx != NULL) tnp->tn_did_filefind_init = TRUE; --- 2977,2992 ---- #else r_ptr = NULL; #endif ! // move the filename one char forward and truncate the ! // filepath with a NUL filename = gettail(buf); STRMOVE(filename + 1, filename); *filename++ = NUL; tnp->tn_search_ctx = vim_findfile_init(buf, filename, r_ptr, 100, ! FALSE, // don't free visited list ! FINDFILE_FILE, // we search for a file tnp->tn_search_ctx, TRUE, curbuf->b_ffname); if (tnp->tn_search_ctx != NULL) tnp->tn_did_filefind_init = TRUE; *************** *** 3024,3030 **** */ static int parse_tag_line( ! char_u *lbuf, /* line to be parsed */ #ifdef FEAT_EMACS_TAGS int is_etag, #endif --- 3020,3026 ---- */ static int parse_tag_line( ! char_u *lbuf, // line to be parsed #ifdef FEAT_EMACS_TAGS int is_etag, #endif *************** *** 3048,3054 **** etag_fail: if (vim_strchr(lbuf, '\n') == NULL) { ! /* Truncated line. Ignore it. */ if (p_verbose >= 5) { verbose_enter(); --- 3044,3050 ---- etag_fail: if (vim_strchr(lbuf, '\n') == NULL) { ! // Truncated line. Ignore it. if (p_verbose >= 5) { verbose_enter(); *************** *** 3063,3088 **** return FAIL; } ! /* Find ^A. If not found the line number is after the 0x7f */ p = vim_strchr(p_7f, Ctrl_A); if (p == NULL) p = p_7f + 1; else ++p; ! if (!VIM_ISDIGIT(*p)) /* check for start of line number */ goto etag_fail; tagp->command = p; ! if (p[-1] == Ctrl_A) /* first format: explicit tagname given */ { tagp->tagname = p_7f + 1; tagp->tagname_end = p - 1; } ! else /* second format: isolate tagname */ { ! /* find end of tagname */ for (p = p_7f - 1; !vim_iswordc(*p); --p) if (p == lbuf) goto etag_fail; --- 3059,3084 ---- return FAIL; } ! // Find ^A. If not found the line number is after the 0x7f p = vim_strchr(p_7f, Ctrl_A); if (p == NULL) p = p_7f + 1; else ++p; ! if (!VIM_ISDIGIT(*p)) // check for start of line number goto etag_fail; tagp->command = p; ! if (p[-1] == Ctrl_A) // first format: explicit tagname given { tagp->tagname = p_7f + 1; tagp->tagname_end = p - 1; } ! else // second format: isolate tagname { ! // find end of tagname for (p = p_7f - 1; !vim_iswordc(*p); --p) if (p == lbuf) goto etag_fail; *************** *** 3092,3098 **** tagp->tagname = p + 1; } } ! else /* not an Emacs tag */ { #endif // Isolate the tagname, from lbuf up to the first white --- 3088,3094 ---- tagp->tagname = p + 1; } } ! else // not an Emacs tag { #endif // Isolate the tagname, from lbuf up to the first white *************** *** 3165,3171 **** { char_u *p = lbuf + 1; ! /* does the same thing as parse_match() */ p += STRLEN(p) + 1; #ifdef FEAT_EMACS_TAGS p += STRLEN(p) + 1; --- 3161,3167 ---- { char_u *p = lbuf + 1; ! // does the same thing as parse_match() p += STRLEN(p) + 1; #ifdef FEAT_EMACS_TAGS p += STRLEN(p) + 1; *************** *** 3185,3192 **** */ static int parse_match( ! char_u *lbuf, /* input: matching line */ ! tagptrs_T *tagp) /* output: pointers into the line */ { int retval; char_u *p; --- 3181,3188 ---- */ static int parse_match( ! char_u *lbuf, // input: matching line ! tagptrs_T *tagp) // output: pointers into the line { int retval; char_u *p; *************** *** 3209,3215 **** } #endif ! /* Find search pattern and the file name for non-etags. */ retval = parse_tag_line(lbuf, #ifdef FEAT_EMACS_TAGS tagp->is_etag, --- 3205,3211 ---- } #endif ! // Find search pattern and the file name for non-etags. retval = parse_tag_line(lbuf, #ifdef FEAT_EMACS_TAGS tagp->is_etag, *************** *** 3223,3229 **** if (retval == OK) { ! /* Try to find a kind field: "kind:" or just ""*/ p = tagp->command; if (find_extra(&p) == OK) { --- 3219,3225 ---- if (retval == OK) { ! // Try to find a kind field: "kind:" or just "" p = tagp->command; if (find_extra(&p) == OK) { *************** *** 3231,3237 **** tagp->command_end = p - 1; // drop trailing bar else tagp->command_end = p; ! p += 2; /* skip ";\"" */ if (*p++ == TAB) while (ASCII_ISALPHA(*p)) { --- 3227,3233 ---- tagp->command_end = p - 1; // drop trailing bar else tagp->command_end = p; ! p += 2; // skip ";\"" if (*p++ == TAB) while (ASCII_ISALPHA(*p)) { *************** *** 3283,3289 **** #ifdef FEAT_EMACS_TAGS if (tagp->is_etag) ! c = 0; /* to shut up GCC */ else #endif { --- 3279,3285 ---- #ifdef FEAT_EMACS_TAGS if (tagp->is_etag) ! c = 0; // to shut up GCC else #endif { *************** *** 3307,3322 **** */ static int jumpto_tag( ! char_u *lbuf_arg, /* line from the tags file for this tag */ ! int forceit, /* :ta with ! */ ! int keep_help) /* keep help flag (FALSE for cscope) */ { int save_secure; int save_magic; int save_p_ws, save_p_scs, save_p_ic; linenr_T save_lnum; char_u *str; ! char_u *pbuf; /* search pattern buffer */ char_u *pbuf_end; char_u *tofree_fname = NULL; char_u *fname; --- 3303,3318 ---- */ static int jumpto_tag( ! char_u *lbuf_arg, // line from the tags file for this tag ! int forceit, // :ta with ! ! int keep_help) // keep help flag (FALSE for cscope) { int save_secure; int save_magic; int save_p_ws, save_p_scs, save_p_ic; linenr_T save_lnum; char_u *str; ! char_u *pbuf; // search pattern buffer char_u *pbuf_end; char_u *tofree_fname = NULL; char_u *fname; *************** *** 3332,3344 **** #endif char_u *full_fname = NULL; #ifdef FEAT_FOLDING ! int old_KeyTyped = KeyTyped; /* getting the file may reset it */ #endif size_t len; char_u *lbuf; ! /* Make a copy of the line, it can become invalid when an autocommand calls ! * back here recursively. */ len = matching_line_len(lbuf_arg) + 1; lbuf = alloc(len); if (lbuf != NULL) --- 3328,3340 ---- #endif char_u *full_fname = NULL; #ifdef FEAT_FOLDING ! int old_KeyTyped = KeyTyped; // getting the file may reset it #endif size_t len; char_u *lbuf; ! // Make a copy of the line, it can become invalid when an autocommand calls ! // back here recursively. len = matching_line_len(lbuf_arg) + 1; lbuf = alloc(len); if (lbuf != NULL) *************** *** 3346,3368 **** pbuf = alloc(LSIZE); ! /* parse the match line into the tagp structure */ if (pbuf == NULL || lbuf == NULL || parse_match(lbuf, &tagp) == FAIL) { tagp.fname_end = NULL; goto erret; } ! /* truncate the file name, so it can be used as a string */ *tagp.fname_end = NUL; fname = tagp.fname; ! /* copy the command to pbuf[], remove trailing CR/NL */ str = tagp.command; for (pbuf_end = pbuf; *str && *str != '\n' && *str != '\r'; ) { #ifdef FEAT_EMACS_TAGS ! if (tagp.is_etag && *str == ',')/* stop at ',' after line number */ break; #endif *pbuf_end++ = *str++; --- 3342,3364 ---- pbuf = alloc(LSIZE); ! // parse the match line into the tagp structure if (pbuf == NULL || lbuf == NULL || parse_match(lbuf, &tagp) == FAIL) { tagp.fname_end = NULL; goto erret; } ! // truncate the file name, so it can be used as a string *tagp.fname_end = NUL; fname = tagp.fname; ! // copy the command to pbuf[], remove trailing CR/NL str = tagp.command; for (pbuf_end = pbuf; *str && *str != '\n' && *str != '\r'; ) { #ifdef FEAT_EMACS_TAGS ! if (tagp.is_etag && *str == ',')// stop at ',' after line number break; #endif *pbuf_end++ = *str++; *************** *** 3393,3399 **** fname = expand_tag_fname(fname, tagp.tag_fname, TRUE); if (fname == NULL) goto erret; ! tofree_fname = fname; /* free() it later */ /* * Check if the file with the tag exists before abandoning the current --- 3389,3395 ---- fname = expand_tag_fname(fname, tagp.tag_fname, TRUE); if (fname == NULL) goto erret; ! tofree_fname = fname; // free() it later /* * Check if the file with the tag exists before abandoning the current *************** *** 3419,3426 **** #if defined(FEAT_QUICKFIX) if (g_do_tagpreview != 0) { ! postponed_split = 0; /* don't split again below */ ! curwin_save = curwin; /* Save current window */ /* * If we are reusing a window, we may change dir when --- 3415,3422 ---- #if defined(FEAT_QUICKFIX) if (g_do_tagpreview != 0) { ! postponed_split = 0; // don't split again below ! curwin_save = curwin; // Save current window /* * If we are reusing a window, we may change dir when *************** *** 3440,3447 **** } } ! /* If it was a CTRL-W CTRL-] command split window now. For ":tab tag" ! * open a new tab page. */ if (postponed_split && (swb_flags & (SWB_USEOPEN | SWB_USETAB))) { buf_T *existing_buf = buflist_findname_exp(fname); --- 3436,3443 ---- } } ! // If it was a CTRL-W CTRL-] command split window now. For ":tab tag" ! // open a new tab page. if (postponed_split && (swb_flags & (SWB_USEOPEN | SWB_USETAB))) { buf_T *existing_buf = buflist_findname_exp(fname); *************** *** 3453,3464 **** if (swb_flags & SWB_USEOPEN) wp = buf_jump_open_win(existing_buf); ! /* If 'switchbuf' contains "usetab": jump to first window in any tab ! * page containing "existing_buf" if one exists */ if (wp == NULL && (swb_flags & SWB_USETAB)) wp = buf_jump_open_tab(existing_buf); ! /* We've switched to the buffer, the usual loading of the file must ! * be skipped. */ if (wp != NULL) getfile_result = GETFILE_SAME_FILE; } --- 3449,3460 ---- if (swb_flags & SWB_USEOPEN) wp = buf_jump_open_win(existing_buf); ! // If 'switchbuf' contains "usetab": jump to first window in any tab ! // page containing "existing_buf" if one exists if (wp == NULL && (swb_flags & SWB_USETAB)) wp = buf_jump_open_tab(existing_buf); ! // We've switched to the buffer, the usual loading of the file must ! // be skipped. if (wp != NULL) getfile_result = GETFILE_SAME_FILE; } *************** *** 3478,3485 **** if (keep_help) { ! /* A :ta from a help file will keep the b_help flag set. For ":ptag" ! * we need to use the flag from the window where we came from. */ #if defined(FEAT_QUICKFIX) if (g_do_tagpreview != 0) keep_help_flag = bt_help(curwin_save->w_buffer); --- 3474,3481 ---- if (keep_help) { ! // A :ta from a help file will keep the b_help flag set. For ":ptag" ! // we need to use the flag from the window where we came from. #if defined(FEAT_QUICKFIX) if (g_do_tagpreview != 0) keep_help_flag = bt_help(curwin_save->w_buffer); *************** *** 3489,3500 **** } if (getfile_result == GETFILE_UNUSED) ! /* Careful: getfile() may trigger autocommands and call jumpto_tag() ! * recursively. */ getfile_result = getfile(0, fname, NULL, TRUE, (linenr_T)0, forceit); keep_help_flag = FALSE; ! if (GETFILE_SUCCESS(getfile_result)) /* got to the right file */ { curwin->w_set_curswant = TRUE; postponed_split = 0; --- 3485,3496 ---- } if (getfile_result == GETFILE_UNUSED) ! // Careful: getfile() may trigger autocommands and call jumpto_tag() ! // recursively. getfile_result = getfile(0, fname, NULL, TRUE, (linenr_T)0, forceit); keep_help_flag = FALSE; ! if (GETFILE_SUCCESS(getfile_result)) // got to the right file { curwin->w_set_curswant = TRUE; postponed_split = 0; *************** *** 3505,3513 **** ++sandbox; #endif save_magic = p_magic; ! p_magic = FALSE; /* always execute with 'nomagic' */ #ifdef FEAT_SEARCH_EXTRA ! /* Save value of no_hlsearch, jumping to a tag is not a real search */ save_no_hlsearch = no_hlsearch; #endif --- 3501,3509 ---- ++sandbox; #endif save_magic = p_magic; ! p_magic = FALSE; // always execute with 'nomagic' #ifdef FEAT_SEARCH_EXTRA ! // Save value of no_hlsearch, jumping to a tag is not a real search save_no_hlsearch = no_hlsearch; #endif *************** *** 3532,3544 **** str = pbuf; if (pbuf[0] == '/' || pbuf[0] == '?') str = skip_regexp(pbuf + 1, pbuf[0], FALSE, NULL) + 1; ! if (str > pbuf_end - 1) /* search command with nothing following */ { save_p_ws = p_ws; save_p_ic = p_ic; save_p_scs = p_scs; ! p_ws = TRUE; /* need 'wrapscan' for backward searches */ ! p_ic = FALSE; /* don't ignore case now */ p_scs = FALSE; save_lnum = curwin->w_cursor.lnum; if (tagp.tagline > 0) --- 3528,3540 ---- str = pbuf; if (pbuf[0] == '/' || pbuf[0] == '?') str = skip_regexp(pbuf + 1, pbuf[0], FALSE, NULL) + 1; ! if (str > pbuf_end - 1) // search command with nothing following { save_p_ws = p_ws; save_p_ic = p_ic; save_p_scs = p_scs; ! p_ws = TRUE; // need 'wrapscan' for backward searches ! p_ic = FALSE; // don't ignore case now p_scs = FALSE; save_lnum = curwin->w_cursor.lnum; if (tagp.tagline > 0) *************** *** 3573,3579 **** if (!do_search(NULL, '/', pbuf, (long)1, search_options, NULL)) { ! /* Guess again: "^char * \w_cursor.lnum = 1; /* start command in line 1 */ do_cmdline_cmd(pbuf); retval = OK; } --- 3605,3617 ---- p_ic = save_p_ic; p_scs = save_p_scs; ! // A search command may have positioned the cursor beyond the end ! // of the line. May need to correct that here. check_cursor(); } else { ! curwin->w_cursor.lnum = 1; // start command in line 1 do_cmdline_cmd(pbuf); retval = OK; } *************** *** 3632,3643 **** --sandbox; #endif #ifdef FEAT_SEARCH_EXTRA ! /* restore no_hlsearch when keeping the old search pattern */ if (search_options) set_no_hlsearch(save_no_hlsearch); #endif ! /* Return OK if jumped to another file (at least we found the file!). */ if (getfile_result == GETFILE_OPEN_OTHER) retval = OK; --- 3628,3639 ---- --sandbox; #endif #ifdef FEAT_SEARCH_EXTRA ! // restore no_hlsearch when keeping the old search pattern if (search_options) set_no_hlsearch(save_no_hlsearch); #endif ! // Return OK if jumped to another file (at least we found the file!). if (getfile_result == GETFILE_OPEN_OTHER) retval = OK; *************** *** 3697,3703 **** erret: #if defined(FEAT_QUICKFIX) ! g_do_tagpreview = 0; /* For next time */ #endif vim_free(lbuf); vim_free(pbuf); --- 3693,3699 ---- erret: #if defined(FEAT_QUICKFIX) ! g_do_tagpreview = 0; // For next time #endif vim_free(lbuf); vim_free(pbuf); *************** *** 3778,3788 **** int retval = FALSE; char_u *fullname; ! if (buf_ffname != NULL) /* if the buffer has a name */ { #ifdef FEAT_EMACS_TAGS if (is_etag) ! c = 0; /* to shut up GCC */ else #endif { --- 3774,3784 ---- int retval = FALSE; char_u *fullname; ! if (buf_ffname != NULL) // if the buffer has a name { #ifdef FEAT_EMACS_TAGS if (is_etag) ! c = 0; // to shut up GCC else #endif { *************** *** 3840,3846 **** if (str == NULL || *str != ';' || !(VIM_ISDIGIT(str[1]) || str[1] == '/' || str[1] == '?')) break; ! ++str; /* skip ';' */ } if (str != NULL && STRNCMP(str, ";\"", 2) == 0) --- 3836,3842 ---- if (str == NULL || *str != ';' || !(VIM_ISDIGIT(str[1]) || str[1] == '/' || str[1] == '?')) break; ! ++str; // skip ';' } if (str != NULL && STRNCMP(str, ";\"", 2) == 0) *************** *** 3863,3869 **** int expand_tags( ! int tagnames, /* expand tag names */ char_u *pat, int *num_file, char_u ***file) --- 3859,3865 ---- int expand_tags( ! int tagnames, // expand tag names char_u *pat, int *num_file, char_u ***file) *************** *** 3889,3897 **** TAG_MANY, curbuf->b_ffname); if (ret == OK && !tagnames) { ! /* Reorganize the tags for display and matching as strings of: ! * "\0\0\0" ! */ for (i = 0; i < *num_file; i++) { parse_match((*file)[i], &t_p); --- 3885,3892 ---- TAG_MANY, curbuf->b_ffname); if (ret == OK && !tagnames) { ! // Reorganize the tags for display and matching as strings of: ! // "\0\0\0" for (i = 0; i < *num_file; i++) { parse_match((*file)[i], &t_p); *************** *** 3918,3931 **** add_tag_field( dict_T *dict, char *field_name, ! char_u *start, /* start of the value */ ! char_u *end) /* after the value; can be NULL */ { char_u *buf; int len = 0; int retval; ! /* check that the field name doesn't exist yet */ if (dict_find(dict, (char_u *)field_name, -1) != NULL) { if (p_verbose > 0) --- 3913,3926 ---- add_tag_field( dict_T *dict, char *field_name, ! char_u *start, // start of the value ! char_u *end) // after the value; can be NULL { char_u *buf; int len = 0; int retval; ! // check that the field name doesn't exist yet if (dict_find(dict, (char_u *)field_name, -1) != NULL) { if (p_verbose > 0) *************** *** 3981,3987 **** parse_match(matches[i], &tp); is_static = test_for_static(&tp); ! /* Skip pseudo-tag lines. */ if (STRNCMP(tp.tagname, "!_TAG_", 6) == 0) continue; --- 3976,3982 ---- parse_match(matches[i], &tp); is_static = test_for_static(&tp); ! // Skip pseudo-tag lines. if (STRNCMP(tp.tagname, "!_TAG_", 6) == 0) continue; *************** *** 4010,4027 **** { if (p == tp.tagkind || (p + 5 == tp.tagkind && STRNCMP(p, "kind:", 5) == 0)) ! /* skip "kind:" and "" */ p = tp.tagkind_end - 1; else if (STRNCMP(p, "file:", 5) == 0) ! /* skip "file:" (static tag) */ p += 4; else if (!VIM_ISWHITE(*p)) { char_u *s, *n; int len; ! /* Add extra field as a dict entry. Fields are ! * separated by Tabs. */ n = p; while (*p != NUL && *p >= ' ' && *p < 127 && *p != ':') ++p; --- 4005,4022 ---- { if (p == tp.tagkind || (p + 5 == tp.tagkind && STRNCMP(p, "kind:", 5) == 0)) ! // skip "kind:" and "" p = tp.tagkind_end - 1; else if (STRNCMP(p, "file:", 5) == 0) ! // skip "file:" (static tag) p += 4; else if (!VIM_ISWHITE(*p)) { char_u *s, *n; int len; ! // Add extra field as a dict entry. Fields are ! // separated by Tabs. n = p; while (*p != NUL && *p >= ' ' && *p < 127 && *p != ':') ++p; *************** *** 4037,4043 **** n[len] = ':'; } else ! /* Skip field without colon. */ while (*p != NUL && *p >= ' ') ++p; if (*p == NUL) --- 4032,4038 ---- n[len] = ':'; } else ! // Skip field without colon. while (*p != NUL && *p >= ' ') ++p; if (*p == NUL) *** ../vim-8.1.2394/src/term.c 2019-11-26 19:33:03.458605263 +0100 --- src/term.c 2019-12-05 21:29:03.087727412 +0100 *************** *** 27,33 **** #ifdef HAVE_TGETENT # ifdef HAVE_TERMIOS_H ! # include /* seems to be required for some Linux */ # endif # ifdef HAVE_TERMCAP_H # include --- 27,33 ---- #ifdef HAVE_TGETENT # ifdef HAVE_TERMIOS_H ! # include // seems to be required for some Linux # endif # ifdef HAVE_TERMCAP_H # include *************** *** 71,77 **** char *bt_string; }; ! /* start of keys that are not directly used by Vim but can be mapped */ #define BT_EXTRA_KEYS 0x101 static void parse_builtin_tcap(char_u *s); --- 71,77 ---- char *bt_string; }; ! // start of keys that are not directly used by Vim but can be mapped #define BT_EXTRA_KEYS 0x101 static void parse_builtin_tcap(char_u *s); *************** *** 97,103 **** char *tgetstr(char *, char **); # ifdef FEAT_TERMRESPONSE ! /* Change this to "if 1" to debug what happens with termresponse. */ # if 0 # define DEBUG_TERMRESPONSE static void log_tr(const char *fmt, ...); --- 97,103 ---- char *tgetstr(char *, char **); # ifdef FEAT_TERMRESPONSE ! // Change this to "if 1" to debug what happens with termresponse. # if 0 # define DEBUG_TERMRESPONSE static void log_tr(const char *fmt, ...); *************** *** 137,152 **** static int bg_b = 255; # endif ! /* Request background color report: */ static termrequest_T rbg_status = TERMREQUEST_INIT; ! /* Request cursor blinking mode report: */ static termrequest_T rbm_status = TERMREQUEST_INIT; ! /* Request cursor style report: */ static termrequest_T rcs_status = TERMREQUEST_INIT; ! /* Request windos position report: */ static termrequest_T winpos_status = TERMREQUEST_INIT; static termrequest_T *all_termrequests[] = { --- 137,152 ---- static int bg_b = 255; # endif ! // Request background color report: static termrequest_T rbg_status = TERMREQUEST_INIT; ! // Request cursor blinking mode report: static termrequest_T rbm_status = TERMREQUEST_INIT; ! // Request cursor style report: static termrequest_T rcs_status = TERMREQUEST_INIT; ! // Request windos position report: static termrequest_T winpos_status = TERMREQUEST_INIT; static termrequest_T *all_termrequests[] = { *************** *** 188,207 **** # define TGETSTR(s, p) vim_tgetstr((s), (p)) # define TGETENT(b, t) tgetent((char *)(b), (char *)(t)) static char_u *vim_tgetstr(char *s, char_u **pp); ! #endif /* HAVE_TGETENT */ ! static int detected_8bit = FALSE; /* detected 8-bit terminal */ #ifdef FEAT_TERMRESPONSE ! /* When the cursor shape was detected these values are used: ! * 1: block, 2: underline, 3: vertical bar */ static int initial_cursor_shape = 0; ! /* The blink flag from the style response may be inverted from the actual ! * blinking state, xterm XORs the flags. */ static int initial_cursor_shape_blink = FALSE; ! /* The blink flag from the blinking-cursor mode response */ static int initial_cursor_blink = FALSE; #endif --- 188,207 ---- # define TGETSTR(s, p) vim_tgetstr((s), (p)) # define TGETENT(b, t) tgetent((char *)(b), (char *)(t)) static char_u *vim_tgetstr(char *s, char_u **pp); ! #endif // HAVE_TGETENT ! static int detected_8bit = FALSE; // detected 8-bit terminal #ifdef FEAT_TERMRESPONSE ! // When the cursor shape was detected these values are used: ! // 1: block, 2: underline, 3: vertical bar static int initial_cursor_shape = 0; ! // The blink flag from the style response may be inverted from the actual ! // blinking state, xterm XORs the flags. static int initial_cursor_shape_blink = FALSE; ! // The blink flag from the blinking-cursor mode response static int initial_cursor_blink = FALSE; #endif *************** *** 231,263 **** {(int)KS_CSV, IF_EB("\033|%d;%dV", ESC_STR "|%d;%dV")}, # endif {(int)KS_CL, IF_EB("\033|C", ESC_STR "|C")}, ! /* attributes switched on with 'h', off with * 'H' */ ! {(int)KS_ME, IF_EB("\033|31H", ESC_STR "|31H")}, /* HL_ALL */ ! {(int)KS_MR, IF_EB("\033|1h", ESC_STR "|1h")}, /* HL_INVERSE */ ! {(int)KS_MD, IF_EB("\033|2h", ESC_STR "|2h")}, /* HL_BOLD */ ! {(int)KS_SE, IF_EB("\033|16H", ESC_STR "|16H")}, /* HL_STANDOUT */ ! {(int)KS_SO, IF_EB("\033|16h", ESC_STR "|16h")}, /* HL_STANDOUT */ ! {(int)KS_UE, IF_EB("\033|8H", ESC_STR "|8H")}, /* HL_UNDERLINE */ ! {(int)KS_US, IF_EB("\033|8h", ESC_STR "|8h")}, /* HL_UNDERLINE */ ! {(int)KS_UCE, IF_EB("\033|8C", ESC_STR "|8C")}, /* HL_UNDERCURL */ ! {(int)KS_UCS, IF_EB("\033|8c", ESC_STR "|8c")}, /* HL_UNDERCURL */ ! {(int)KS_STE, IF_EB("\033|4C", ESC_STR "|4C")}, /* HL_STRIKETHROUGH */ ! {(int)KS_STS, IF_EB("\033|4c", ESC_STR "|4c")}, /* HL_STRIKETHROUGH */ ! {(int)KS_CZR, IF_EB("\033|4H", ESC_STR "|4H")}, /* HL_ITALIC */ ! {(int)KS_CZH, IF_EB("\033|4h", ESC_STR "|4h")}, /* HL_ITALIC */ {(int)KS_VB, IF_EB("\033|f", ESC_STR "|f")}, {(int)KS_MS, "y"}, {(int)KS_UT, "y"}, {(int)KS_XN, "y"}, ! {(int)KS_LE, "\b"}, /* cursor-left = BS */ ! {(int)KS_ND, "\014"}, /* cursor-right = CTRL-L */ # ifdef TERMINFO {(int)KS_CM, IF_EB("\033|%p1%d;%p2%dM", ESC_STR "|%p1%d;%p2%dM")}, # else {(int)KS_CM, IF_EB("\033|%d;%dM", ESC_STR "|%d;%dM")}, # endif ! /* there are no key sequences here, the GUI sequences are recognized ! * in check_termcode() */ #endif #ifndef NO_BUILTIN_TCAPS --- 231,263 ---- {(int)KS_CSV, IF_EB("\033|%d;%dV", ESC_STR "|%d;%dV")}, # endif {(int)KS_CL, IF_EB("\033|C", ESC_STR "|C")}, ! // attributes switched on with 'h', off with * 'H' ! {(int)KS_ME, IF_EB("\033|31H", ESC_STR "|31H")}, // HL_ALL ! {(int)KS_MR, IF_EB("\033|1h", ESC_STR "|1h")}, // HL_INVERSE ! {(int)KS_MD, IF_EB("\033|2h", ESC_STR "|2h")}, // HL_BOLD ! {(int)KS_SE, IF_EB("\033|16H", ESC_STR "|16H")}, // HL_STANDOUT ! {(int)KS_SO, IF_EB("\033|16h", ESC_STR "|16h")}, // HL_STANDOUT ! {(int)KS_UE, IF_EB("\033|8H", ESC_STR "|8H")}, // HL_UNDERLINE ! {(int)KS_US, IF_EB("\033|8h", ESC_STR "|8h")}, // HL_UNDERLINE ! {(int)KS_UCE, IF_EB("\033|8C", ESC_STR "|8C")}, // HL_UNDERCURL ! {(int)KS_UCS, IF_EB("\033|8c", ESC_STR "|8c")}, // HL_UNDERCURL ! {(int)KS_STE, IF_EB("\033|4C", ESC_STR "|4C")}, // HL_STRIKETHROUGH ! {(int)KS_STS, IF_EB("\033|4c", ESC_STR "|4c")}, // HL_STRIKETHROUGH ! {(int)KS_CZR, IF_EB("\033|4H", ESC_STR "|4H")}, // HL_ITALIC ! {(int)KS_CZH, IF_EB("\033|4h", ESC_STR "|4h")}, // HL_ITALIC {(int)KS_VB, IF_EB("\033|f", ESC_STR "|f")}, {(int)KS_MS, "y"}, {(int)KS_UT, "y"}, {(int)KS_XN, "y"}, ! {(int)KS_LE, "\b"}, // cursor-left = BS ! {(int)KS_ND, "\014"}, // cursor-right = CTRL-L # ifdef TERMINFO {(int)KS_CM, IF_EB("\033|%p1%d;%p2%dM", ESC_STR "|%p1%d;%p2%dM")}, # else {(int)KS_CM, IF_EB("\033|%d;%dM", ESC_STR "|%d;%dM")}, # endif ! // there are no key sequences here, the GUI sequences are recognized ! // in check_termcode() #endif #ifndef NO_BUILTIN_TCAPS *************** *** 294,311 **** {(int)KS_CZH, "\033[3m"}, {(int)KS_CZR, "\033[0m"}, #if defined(__MORPHOS__) || defined(__AROS__) ! {(int)KS_CCO, "8"}, /* allow 8 colors */ # ifdef TERMINFO ! {(int)KS_CAB, "\033[4%p1%dm"},/* set background color */ ! {(int)KS_CAF, "\033[3%p1%dm"},/* set foreground color */ # else ! {(int)KS_CAB, "\033[4%dm"}, /* set background color */ ! {(int)KS_CAF, "\033[3%dm"}, /* set foreground color */ # endif ! {(int)KS_OP, "\033[m"}, /* reset colors */ #endif {(int)KS_MS, "y"}, ! {(int)KS_UT, "y"}, /* guessed */ {(int)KS_LE, "\b"}, # ifdef TERMINFO {(int)KS_CM, "\033[%i%p1%d;%p2%dH"}, --- 294,311 ---- {(int)KS_CZH, "\033[3m"}, {(int)KS_CZR, "\033[0m"}, #if defined(__MORPHOS__) || defined(__AROS__) ! {(int)KS_CCO, "8"}, // allow 8 colors # ifdef TERMINFO ! {(int)KS_CAB, "\033[4%p1%dm"},// set background color ! {(int)KS_CAF, "\033[3%p1%dm"},// set foreground color # else ! {(int)KS_CAB, "\033[4%dm"}, // set background color ! {(int)KS_CAF, "\033[3%dm"}, // set foreground color # endif ! {(int)KS_OP, "\033[m"}, // reset colors #endif {(int)KS_MS, "y"}, ! {(int)KS_UT, "y"}, // guessed {(int)KS_LE, "\b"}, # ifdef TERMINFO {(int)KS_CM, "\033[%i%p1%d;%p2%dH"}, *************** *** 329,335 **** {K_S_LEFT, "\233 A"}, {K_S_RIGHT, "\233 @"}, {K_S_TAB, "\233Z"}, ! {K_F1, "\233\060~"},/* some compilers don't dig "\2330" */ {K_F2, "\233\061~"}, {K_F3, "\233\062~"}, {K_F4, "\233\063~"}, --- 329,335 ---- {K_S_LEFT, "\233 A"}, {K_S_RIGHT, "\233 @"}, {K_S_TAB, "\233Z"}, ! {K_F1, "\233\060~"},// some compilers don't dig "\2330" {K_F2, "\233\061~"}, {K_F3, "\233\062~"}, {K_F4, "\233\063~"}, *************** *** 350,365 **** {K_S_F9, "\233\061\070~"}, {K_S_F10, "\233\061\071~"}, {K_HELP, "\233?~"}, ! {K_INS, "\233\064\060~"}, /* 101 key keyboard */ ! {K_PAGEUP, "\233\064\061~"}, /* 101 key keyboard */ ! {K_PAGEDOWN, "\233\064\062~"}, /* 101 key keyboard */ ! {K_HOME, "\233\064\064~"}, /* 101 key keyboard */ ! {K_END, "\233\064\065~"}, /* 101 key keyboard */ {BT_EXTRA_KEYS, ""}, ! {TERMCAP2KEY('#', '2'), "\233\065\064~"}, /* shifted home key */ ! {TERMCAP2KEY('#', '3'), "\233\065\060~"}, /* shifted insert key */ ! {TERMCAP2KEY('*', '7'), "\233\065\065~"}, /* shifted end key */ # endif # if defined(__BEOS__) || defined(ALL_BUILTIN_TCAPS) --- 350,365 ---- {K_S_F9, "\233\061\070~"}, {K_S_F10, "\233\061\071~"}, {K_HELP, "\233?~"}, ! {K_INS, "\233\064\060~"}, // 101 key keyboard ! {K_PAGEUP, "\233\064\061~"}, // 101 key keyboard ! {K_PAGEDOWN, "\233\064\062~"}, // 101 key keyboard ! {K_HOME, "\233\064\064~"}, // 101 key keyboard ! {K_END, "\233\064\065~"}, // 101 key keyboard {BT_EXTRA_KEYS, ""}, ! {TERMCAP2KEY('#', '2'), "\233\065\064~"}, // shifted home key ! {TERMCAP2KEY('#', '3'), "\233\065\060~"}, // shifted insert key ! {TERMCAP2KEY('*', '7'), "\233\065\065~"}, // shifted end key # endif # if defined(__BEOS__) || defined(ALL_BUILTIN_TCAPS) *************** *** 385,418 **** # ifdef TERMINFO {(int)KS_CS, "\033[%i%p1%d;%p2%dr"}, # else ! {(int)KS_CS, "\033[%i%d;%dr"}, /* scroll region */ # endif #endif {(int)KS_CL, "\033[H\033[2J"}, #ifdef notyet ! {(int)KS_VI, "[VI]"}, /* cursor invisible, VT320: CSI ? 25 l */ ! {(int)KS_VE, "[VE]"}, /* cursor visible, VT320: CSI ? 25 h */ #endif ! {(int)KS_ME, "\033[m"}, /* normal mode */ ! {(int)KS_MR, "\033[7m"}, /* reverse */ ! {(int)KS_MD, "\033[1m"}, /* bold */ ! {(int)KS_SO, "\033[31m"}, /* standout mode: red */ ! {(int)KS_SE, "\033[m"}, /* standout end */ ! {(int)KS_CZH, "\033[35m"}, /* italic: purple */ ! {(int)KS_CZR, "\033[m"}, /* italic end */ ! {(int)KS_US, "\033[4m"}, /* underscore mode */ ! {(int)KS_UE, "\033[m"}, /* underscore end */ ! {(int)KS_CCO, "8"}, /* allow 8 colors */ ! # ifdef TERMINFO ! {(int)KS_CAB, "\033[4%p1%dm"},/* set background color */ ! {(int)KS_CAF, "\033[3%p1%dm"},/* set foreground color */ ! # else ! {(int)KS_CAB, "\033[4%dm"}, /* set background color */ ! {(int)KS_CAF, "\033[3%dm"}, /* set foreground color */ ! # endif ! {(int)KS_OP, "\033[m"}, /* reset colors */ ! {(int)KS_MS, "y"}, /* safe to move cur in reverse mode */ ! {(int)KS_UT, "y"}, /* guessed */ {(int)KS_LE, "\b"}, # ifdef TERMINFO {(int)KS_CM, "\033[%i%p1%d;%p2%dH"}, --- 385,418 ---- # ifdef TERMINFO {(int)KS_CS, "\033[%i%p1%d;%p2%dr"}, # else ! {(int)KS_CS, "\033[%i%d;%dr"}, // scroll region # endif #endif {(int)KS_CL, "\033[H\033[2J"}, #ifdef notyet ! {(int)KS_VI, "[VI]"}, // cursor invisible, VT320: CSI ? 25 l ! {(int)KS_VE, "[VE]"}, // cursor visible, VT320: CSI ? 25 h #endif ! {(int)KS_ME, "\033[m"}, // normal mode ! {(int)KS_MR, "\033[7m"}, // reverse ! {(int)KS_MD, "\033[1m"}, // bold ! {(int)KS_SO, "\033[31m"}, // standout mode: red ! {(int)KS_SE, "\033[m"}, // standout end ! {(int)KS_CZH, "\033[35m"}, // italic: purple ! {(int)KS_CZR, "\033[m"}, // italic end ! {(int)KS_US, "\033[4m"}, // underscore mode ! {(int)KS_UE, "\033[m"}, // underscore end ! {(int)KS_CCO, "8"}, // allow 8 colors ! # ifdef TERMINFO ! {(int)KS_CAB, "\033[4%p1%dm"},// set background color ! {(int)KS_CAF, "\033[3%p1%dm"},// set foreground color ! # else ! {(int)KS_CAB, "\033[4%dm"}, // set background color ! {(int)KS_CAF, "\033[3%dm"}, // set foreground color ! # endif ! {(int)KS_OP, "\033[m"}, // reset colors ! {(int)KS_MS, "y"}, // safe to move cur in reverse mode ! {(int)KS_UT, "y"}, // guessed {(int)KS_LE, "\b"}, # ifdef TERMINFO {(int)KS_CM, "\033[%i%p1%d;%p2%dH"}, *************** *** 426,432 **** {(int)KS_CRI, "\033[%dC"}, # endif # if defined(BEOS_DR8) ! {(int)KS_DB, ""}, /* hack! see screen.c */ # endif {K_UP, "\033[A"}, --- 426,432 ---- {(int)KS_CRI, "\033[%dC"}, # endif # if defined(BEOS_DR8) ! {(int)KS_DB, ""}, // hack! see screen.c # endif {K_UP, "\033[A"}, *************** *** 457,463 **** {(int)KS_ME, IF_EB("\033[0m", ESC_STR "[0m")}, {(int)KS_MR, IF_EB("\033[7m", ESC_STR "[7m")}, {(int)KS_MS, "y"}, ! {(int)KS_UT, "y"}, /* guessed */ {(int)KS_LE, "\b"}, # ifdef TERMINFO {(int)KS_CM, IF_EB("\033[%i%p1%d;%p2%dH", ESC_STR "[%i%p1%d;%p2%dH")}, --- 457,463 ---- {(int)KS_ME, IF_EB("\033[0m", ESC_STR "[0m")}, {(int)KS_MR, IF_EB("\033[7m", ESC_STR "[7m")}, {(int)KS_MS, "y"}, ! {(int)KS_UT, "y"}, // guessed {(int)KS_LE, "\b"}, # ifdef TERMINFO {(int)KS_CM, IF_EB("\033[%i%p1%d;%p2%dH", ESC_STR "[%i%p1%d;%p2%dH")}, *************** *** 484,508 **** {(int)KS_CE, "\033[K"}, {(int)KS_CL, "\033[2J"}, {(int)KS_ME, "\033[0m"}, ! {(int)KS_MR, "\033[5m"}, /* reverse: black on lightgrey */ ! {(int)KS_MD, "\033[1m"}, /* bold: white text */ ! {(int)KS_SE, "\033[0m"}, /* standout end */ ! {(int)KS_SO, "\033[31m"}, /* standout: white on blue */ ! {(int)KS_CZH, "\033[34;43m"}, /* italic mode: blue text on yellow */ ! {(int)KS_CZR, "\033[0m"}, /* italic mode end */ ! {(int)KS_US, "\033[36;41m"}, /* underscore mode: cyan text on red */ ! {(int)KS_UE, "\033[0m"}, /* underscore mode end */ ! {(int)KS_CCO, "8"}, /* allow 8 colors */ # ifdef TERMINFO ! {(int)KS_CAB, "\033[4%p1%dm"},/* set background color */ ! {(int)KS_CAF, "\033[3%p1%dm"},/* set foreground color */ # else ! {(int)KS_CAB, "\033[4%dm"}, /* set background color */ ! {(int)KS_CAF, "\033[3%dm"}, /* set foreground color */ # endif ! {(int)KS_OP, "\033[0m"}, /* reset colors */ {(int)KS_MS, "y"}, ! {(int)KS_UT, "y"}, /* guessed */ {(int)KS_LE, "\b"}, # ifdef TERMINFO {(int)KS_CM, "\033[%i%p1%d;%p2%dH"}, --- 484,508 ---- {(int)KS_CE, "\033[K"}, {(int)KS_CL, "\033[2J"}, {(int)KS_ME, "\033[0m"}, ! {(int)KS_MR, "\033[5m"}, // reverse: black on lightgrey ! {(int)KS_MD, "\033[1m"}, // bold: white text ! {(int)KS_SE, "\033[0m"}, // standout end ! {(int)KS_SO, "\033[31m"}, // standout: white on blue ! {(int)KS_CZH, "\033[34;43m"}, // italic mode: blue text on yellow ! {(int)KS_CZR, "\033[0m"}, // italic mode end ! {(int)KS_US, "\033[36;41m"}, // underscore mode: cyan text on red ! {(int)KS_UE, "\033[0m"}, // underscore mode end ! {(int)KS_CCO, "8"}, // allow 8 colors # ifdef TERMINFO ! {(int)KS_CAB, "\033[4%p1%dm"},// set background color ! {(int)KS_CAF, "\033[3%p1%dm"},// set foreground color # else ! {(int)KS_CAB, "\033[4%dm"}, // set background color ! {(int)KS_CAF, "\033[3%dm"}, // set foreground color # endif ! {(int)KS_OP, "\033[0m"}, // reset colors {(int)KS_MS, "y"}, ! {(int)KS_UT, "y"}, // guessed {(int)KS_LE, "\b"}, # ifdef TERMINFO {(int)KS_CM, "\033[%i%p1%d;%p2%dH"}, *************** *** 530,537 **** {K_F8, "\316B"}, {K_F9, "\316C"}, {K_F10, "\316D"}, ! {K_F11, "\316\205"}, /* guessed */ ! {K_F12, "\316\206"}, /* guessed */ {K_S_F1, "\316T"}, {K_S_F2, "\316U"}, {K_S_F3, "\316V"}, --- 530,537 ---- {K_F8, "\316B"}, {K_F9, "\316C"}, {K_F10, "\316D"}, ! {K_F11, "\316\205"}, // guessed ! {K_F12, "\316\206"}, // guessed {K_S_F1, "\316T"}, {K_S_F2, "\316U"}, {K_S_F3, "\316V"}, *************** *** 542,549 **** {K_S_F8, "\316["}, {K_S_F9, "\316\\"}, {K_S_F10, "\316]"}, ! {K_S_F11, "\316\207"}, /* guessed */ ! {K_S_F12, "\316\210"}, /* guessed */ {K_INS, "\316R"}, {K_DEL, "\316S"}, {K_HOME, "\316G"}, --- 542,549 ---- {K_S_F8, "\316["}, {K_S_F9, "\316\\"}, {K_S_F10, "\316]"}, ! {K_S_F11, "\316\207"}, // guessed ! {K_S_F12, "\316\210"}, // guessed {K_INS, "\316R"}, {K_DEL, "\316S"}, {K_HOME, "\316G"}, *************** *** 708,726 **** # endif {(int)KS_CL, IF_EB("\033[H\033[2J", ESC_STR "[H" ESC_STR_nc "[2J")}, {(int)KS_CD, IF_EB("\033[J", ESC_STR "[J")}, ! {(int)KS_CCO, "8"}, /* allow 8 colors */ {(int)KS_ME, IF_EB("\033[0m", ESC_STR "[0m")}, {(int)KS_MR, IF_EB("\033[7m", ESC_STR "[7m")}, ! {(int)KS_MD, IF_EB("\033[1m", ESC_STR "[1m")}, /* bold mode */ ! {(int)KS_SE, IF_EB("\033[22m", ESC_STR "[22m")},/* normal mode */ ! {(int)KS_UE, IF_EB("\033[24m", ESC_STR "[24m")},/* exit underscore mode */ ! {(int)KS_US, IF_EB("\033[4m", ESC_STR "[4m")}, /* underscore mode */ ! {(int)KS_CZH, IF_EB("\033[34;43m", ESC_STR "[34;43m")}, /* italic mode: blue text on yellow */ ! {(int)KS_CZR, IF_EB("\033[0m", ESC_STR "[0m")}, /* italic mode end */ ! {(int)KS_CAB, IF_EB("\033[4%dm", ESC_STR "[4%dm")}, /* set background color (ANSI) */ ! {(int)KS_CAF, IF_EB("\033[3%dm", ESC_STR "[3%dm")}, /* set foreground color (ANSI) */ ! {(int)KS_CSB, IF_EB("\033[102;%dm", ESC_STR "[102;%dm")}, /* set screen background color */ ! {(int)KS_CSF, IF_EB("\033[101;%dm", ESC_STR "[101;%dm")}, /* set screen foreground color */ {(int)KS_MS, "y"}, {(int)KS_UT, "y"}, {(int)KS_XN, "y"}, --- 708,726 ---- # endif {(int)KS_CL, IF_EB("\033[H\033[2J", ESC_STR "[H" ESC_STR_nc "[2J")}, {(int)KS_CD, IF_EB("\033[J", ESC_STR "[J")}, ! {(int)KS_CCO, "8"}, // allow 8 colors {(int)KS_ME, IF_EB("\033[0m", ESC_STR "[0m")}, {(int)KS_MR, IF_EB("\033[7m", ESC_STR "[7m")}, ! {(int)KS_MD, IF_EB("\033[1m", ESC_STR "[1m")}, // bold mode ! {(int)KS_SE, IF_EB("\033[22m", ESC_STR "[22m")},// normal mode ! {(int)KS_UE, IF_EB("\033[24m", ESC_STR "[24m")},// exit underscore mode ! {(int)KS_US, IF_EB("\033[4m", ESC_STR "[4m")}, // underscore mode ! {(int)KS_CZH, IF_EB("\033[34;43m", ESC_STR "[34;43m")}, // italic mode: blue text on yellow ! {(int)KS_CZR, IF_EB("\033[0m", ESC_STR "[0m")}, // italic mode end ! {(int)KS_CAB, IF_EB("\033[4%dm", ESC_STR "[4%dm")}, // set background color (ANSI) ! {(int)KS_CAF, IF_EB("\033[3%dm", ESC_STR "[3%dm")}, // set foreground color (ANSI) ! {(int)KS_CSB, IF_EB("\033[102;%dm", ESC_STR "[102;%dm")}, // set screen background color ! {(int)KS_CSF, IF_EB("\033[101;%dm", ESC_STR "[101;%dm")}, // set screen foreground color {(int)KS_MS, "y"}, {(int)KS_UT, "y"}, {(int)KS_XN, "y"}, *************** *** 756,763 **** {K_F12, IF_EB("\033[24~", ESC_STR "[24~")}, {K_F13, IF_EB("\033[25~", ESC_STR "[25~")}, {K_F14, IF_EB("\033[26~", ESC_STR "[26~")}, ! {K_F15, IF_EB("\033[28~", ESC_STR "[28~")}, /* Help */ ! {K_F16, IF_EB("\033[29~", ESC_STR "[29~")}, /* Select */ {K_F17, IF_EB("\033[31~", ESC_STR "[31~")}, {K_F18, IF_EB("\033[32~", ESC_STR "[32~")}, {K_F19, IF_EB("\033[33~", ESC_STR "[33~")}, --- 756,763 ---- {K_F12, IF_EB("\033[24~", ESC_STR "[24~")}, {K_F13, IF_EB("\033[25~", ESC_STR "[25~")}, {K_F14, IF_EB("\033[26~", ESC_STR "[26~")}, ! {K_F15, IF_EB("\033[28~", ESC_STR "[28~")}, // Help ! {K_F16, IF_EB("\033[29~", ESC_STR "[29~")}, // Select {K_F17, IF_EB("\033[31~", ESC_STR "[31~")}, {K_F18, IF_EB("\033[32~", ESC_STR "[32~")}, {K_F19, IF_EB("\033[33~", ESC_STR "[33~")}, *************** *** 770,791 **** {K_PAGEDOWN, IF_EB("\033[6~", ESC_STR "[6~")}, // These sequences starting with O may interfere with what the user // is typing. Remove these if that bothers you. ! {K_KPLUS, IF_EB("\033Ok", ESC_STR "Ok")}, /* keypad plus */ ! {K_KMINUS, IF_EB("\033Om", ESC_STR "Om")}, /* keypad minus */ ! {K_KDIVIDE, IF_EB("\033Oo", ESC_STR "Oo")}, /* keypad / */ ! {K_KMULTIPLY, IF_EB("\033Oj", ESC_STR "Oj")}, /* keypad * */ ! {K_KENTER, IF_EB("\033OM", ESC_STR "OM")}, /* keypad Enter */ ! {K_K0, IF_EB("\033Op", ESC_STR "Op")}, /* keypad 0 */ ! {K_K1, IF_EB("\033Oq", ESC_STR "Oq")}, /* keypad 1 */ ! {K_K2, IF_EB("\033Or", ESC_STR "Or")}, /* keypad 2 */ ! {K_K3, IF_EB("\033Os", ESC_STR "Os")}, /* keypad 3 */ ! {K_K4, IF_EB("\033Ot", ESC_STR "Ot")}, /* keypad 4 */ ! {K_K5, IF_EB("\033Ou", ESC_STR "Ou")}, /* keypad 5 */ ! {K_K6, IF_EB("\033Ov", ESC_STR "Ov")}, /* keypad 6 */ ! {K_K7, IF_EB("\033Ow", ESC_STR "Ow")}, /* keypad 7 */ ! {K_K8, IF_EB("\033Ox", ESC_STR "Ox")}, /* keypad 8 */ ! {K_K9, IF_EB("\033Oy", ESC_STR "Oy")}, /* keypad 9 */ ! {K_BS, "\x7f"}, /* for some reason 0177 doesn't work */ # endif # if defined(ALL_BUILTIN_TCAPS) || defined(__MINT__) --- 770,791 ---- {K_PAGEDOWN, IF_EB("\033[6~", ESC_STR "[6~")}, // These sequences starting with O may interfere with what the user // is typing. Remove these if that bothers you. ! {K_KPLUS, IF_EB("\033Ok", ESC_STR "Ok")}, // keypad plus ! {K_KMINUS, IF_EB("\033Om", ESC_STR "Om")}, // keypad minus ! {K_KDIVIDE, IF_EB("\033Oo", ESC_STR "Oo")}, // keypad / ! {K_KMULTIPLY, IF_EB("\033Oj", ESC_STR "Oj")}, // keypad * ! {K_KENTER, IF_EB("\033OM", ESC_STR "OM")}, // keypad Enter ! {K_K0, IF_EB("\033Op", ESC_STR "Op")}, // keypad 0 ! {K_K1, IF_EB("\033Oq", ESC_STR "Oq")}, // keypad 1 ! {K_K2, IF_EB("\033Or", ESC_STR "Or")}, // keypad 2 ! {K_K3, IF_EB("\033Os", ESC_STR "Os")}, // keypad 3 ! {K_K4, IF_EB("\033Ot", ESC_STR "Ot")}, // keypad 4 ! {K_K5, IF_EB("\033Ou", ESC_STR "Ou")}, // keypad 5 ! {K_K6, IF_EB("\033Ov", ESC_STR "Ov")}, // keypad 6 ! {K_K7, IF_EB("\033Ow", ESC_STR "Ow")}, // keypad 7 ! {K_K8, IF_EB("\033Ox", ESC_STR "Ox")}, // keypad 8 ! {K_K9, IF_EB("\033Oy", ESC_STR "Oy")}, // keypad 9 ! {K_BS, "\x7f"}, // for some reason 0177 doesn't work # endif # if defined(ALL_BUILTIN_TCAPS) || defined(__MINT__) *************** *** 936,942 **** {(int)KS_RBG, IF_EB("\033]11;?\007", ESC_STR "]11;?\007")}, {(int)KS_U7, IF_EB("\033[6n", ESC_STR "[6n")}, # ifdef FEAT_TERMGUICOLORS ! /* These are printf strings, not terminal codes. */ {(int)KS_8F, IF_EB("\033[38;2;%lu;%lu;%lum", ESC_STR "[38;2;%lu;%lu;%lum")}, {(int)KS_8B, IF_EB("\033[48;2;%lu;%lu;%lum", ESC_STR "[48;2;%lu;%lu;%lum")}, # endif --- 936,942 ---- {(int)KS_RBG, IF_EB("\033]11;?\007", ESC_STR "]11;?\007")}, {(int)KS_U7, IF_EB("\033[6n", ESC_STR "[6n")}, # ifdef FEAT_TERMGUICOLORS ! // These are printf strings, not terminal codes. {(int)KS_8F, IF_EB("\033[38;2;%lu;%lu;%lum", ESC_STR "[38;2;%lu;%lu;%lum")}, {(int)KS_8B, IF_EB("\033[48;2;%lu;%lu;%lum", ESC_STR "[48;2;%lu;%lu;%lum")}, # endif *************** *** 951,962 **** {K_DOWN, IF_EB("\033O*B", ESC_STR "O*B")}, {K_RIGHT, IF_EB("\033O*C", ESC_STR "O*C")}, {K_LEFT, IF_EB("\033O*D", ESC_STR "O*D")}, ! /* An extra set of cursor keys for vt100 mode */ {K_XUP, IF_EB("\033[1;*A", ESC_STR "[1;*A")}, {K_XDOWN, IF_EB("\033[1;*B", ESC_STR "[1;*B")}, {K_XRIGHT, IF_EB("\033[1;*C", ESC_STR "[1;*C")}, {K_XLEFT, IF_EB("\033[1;*D", ESC_STR "[1;*D")}, ! /* An extra set of function keys for vt100 mode */ {K_XF1, IF_EB("\033O*P", ESC_STR "O*P")}, {K_XF2, IF_EB("\033O*Q", ESC_STR "O*Q")}, {K_XF3, IF_EB("\033O*R", ESC_STR "O*R")}, --- 951,962 ---- {K_DOWN, IF_EB("\033O*B", ESC_STR "O*B")}, {K_RIGHT, IF_EB("\033O*C", ESC_STR "O*C")}, {K_LEFT, IF_EB("\033O*D", ESC_STR "O*D")}, ! // An extra set of cursor keys for vt100 mode {K_XUP, IF_EB("\033[1;*A", ESC_STR "[1;*A")}, {K_XDOWN, IF_EB("\033[1;*B", ESC_STR "[1;*B")}, {K_XRIGHT, IF_EB("\033[1;*C", ESC_STR "[1;*C")}, {K_XLEFT, IF_EB("\033[1;*D", ESC_STR "[1;*D")}, ! // An extra set of function keys for vt100 mode {K_XF1, IF_EB("\033O*P", ESC_STR "O*P")}, {K_XF2, IF_EB("\033O*Q", ESC_STR "O*Q")}, {K_XF3, IF_EB("\033O*R", ESC_STR "O*R")}, *************** *** 978,1045 **** {K_UNDO, IF_EB("\033[26;*~", ESC_STR "[26;*~")}, {K_INS, IF_EB("\033[2;*~", ESC_STR "[2;*~")}, {K_HOME, IF_EB("\033[1;*H", ESC_STR "[1;*H")}, ! /* {K_S_HOME, IF_EB("\033O2H", ESC_STR "O2H")}, */ ! /* {K_C_HOME, IF_EB("\033O5H", ESC_STR "O5H")}, */ {K_KHOME, IF_EB("\033[1;*~", ESC_STR "[1;*~")}, ! {K_XHOME, IF_EB("\033O*H", ESC_STR "O*H")}, /* other Home */ ! {K_ZHOME, IF_EB("\033[7;*~", ESC_STR "[7;*~")}, /* other Home */ {K_END, IF_EB("\033[1;*F", ESC_STR "[1;*F")}, ! /* {K_S_END, IF_EB("\033O2F", ESC_STR "O2F")}, */ ! /* {K_C_END, IF_EB("\033O5F", ESC_STR "O5F")}, */ {K_KEND, IF_EB("\033[4;*~", ESC_STR "[4;*~")}, ! {K_XEND, IF_EB("\033O*F", ESC_STR "O*F")}, /* other End */ {K_ZEND, IF_EB("\033[8;*~", ESC_STR "[8;*~")}, {K_PAGEUP, IF_EB("\033[5;*~", ESC_STR "[5;*~")}, {K_PAGEDOWN, IF_EB("\033[6;*~", ESC_STR "[6;*~")}, ! {K_KPLUS, IF_EB("\033O*k", ESC_STR "O*k")}, /* keypad plus */ ! {K_KMINUS, IF_EB("\033O*m", ESC_STR "O*m")}, /* keypad minus */ ! {K_KDIVIDE, IF_EB("\033O*o", ESC_STR "O*o")}, /* keypad / */ ! {K_KMULTIPLY, IF_EB("\033O*j", ESC_STR "O*j")}, /* keypad * */ ! {K_KENTER, IF_EB("\033O*M", ESC_STR "O*M")}, /* keypad Enter */ ! {K_KPOINT, IF_EB("\033O*n", ESC_STR "O*n")}, /* keypad . */ ! {K_K0, IF_EB("\033O*p", ESC_STR "O*p")}, /* keypad 0 */ ! {K_K1, IF_EB("\033O*q", ESC_STR "O*q")}, /* keypad 1 */ ! {K_K2, IF_EB("\033O*r", ESC_STR "O*r")}, /* keypad 2 */ ! {K_K3, IF_EB("\033O*s", ESC_STR "O*s")}, /* keypad 3 */ ! {K_K4, IF_EB("\033O*t", ESC_STR "O*t")}, /* keypad 4 */ ! {K_K5, IF_EB("\033O*u", ESC_STR "O*u")}, /* keypad 5 */ ! {K_K6, IF_EB("\033O*v", ESC_STR "O*v")}, /* keypad 6 */ ! {K_K7, IF_EB("\033O*w", ESC_STR "O*w")}, /* keypad 7 */ ! {K_K8, IF_EB("\033O*x", ESC_STR "O*x")}, /* keypad 8 */ ! {K_K9, IF_EB("\033O*y", ESC_STR "O*y")}, /* keypad 9 */ ! {K_KDEL, IF_EB("\033[3;*~", ESC_STR "[3;*~")}, /* keypad Del */ ! {K_PS, IF_EB("\033[200~", ESC_STR "[200~")}, /* paste start */ ! {K_PE, IF_EB("\033[201~", ESC_STR "[201~")}, /* paste end */ {BT_EXTRA_KEYS, ""}, ! {TERMCAP2KEY('k', '0'), IF_EB("\033[10;*~", ESC_STR "[10;*~")}, /* F0 */ ! {TERMCAP2KEY('F', '3'), IF_EB("\033[25;*~", ESC_STR "[25;*~")}, /* F13 */ ! /* F14 and F15 are missing, because they send the same codes as the undo ! * and help key, although they don't work on all keyboards. */ ! {TERMCAP2KEY('F', '6'), IF_EB("\033[29;*~", ESC_STR "[29;*~")}, /* F16 */ ! {TERMCAP2KEY('F', '7'), IF_EB("\033[31;*~", ESC_STR "[31;*~")}, /* F17 */ ! {TERMCAP2KEY('F', '8'), IF_EB("\033[32;*~", ESC_STR "[32;*~")}, /* F18 */ ! {TERMCAP2KEY('F', '9'), IF_EB("\033[33;*~", ESC_STR "[33;*~")}, /* F19 */ ! {TERMCAP2KEY('F', 'A'), IF_EB("\033[34;*~", ESC_STR "[34;*~")}, /* F20 */ ! ! {TERMCAP2KEY('F', 'B'), IF_EB("\033[42;*~", ESC_STR "[42;*~")}, /* F21 */ ! {TERMCAP2KEY('F', 'C'), IF_EB("\033[43;*~", ESC_STR "[43;*~")}, /* F22 */ ! {TERMCAP2KEY('F', 'D'), IF_EB("\033[44;*~", ESC_STR "[44;*~")}, /* F23 */ ! {TERMCAP2KEY('F', 'E'), IF_EB("\033[45;*~", ESC_STR "[45;*~")}, /* F24 */ ! {TERMCAP2KEY('F', 'F'), IF_EB("\033[46;*~", ESC_STR "[46;*~")}, /* F25 */ ! {TERMCAP2KEY('F', 'G'), IF_EB("\033[47;*~", ESC_STR "[47;*~")}, /* F26 */ ! {TERMCAP2KEY('F', 'H'), IF_EB("\033[48;*~", ESC_STR "[48;*~")}, /* F27 */ ! {TERMCAP2KEY('F', 'I'), IF_EB("\033[49;*~", ESC_STR "[49;*~")}, /* F28 */ ! {TERMCAP2KEY('F', 'J'), IF_EB("\033[50;*~", ESC_STR "[50;*~")}, /* F29 */ ! {TERMCAP2KEY('F', 'K'), IF_EB("\033[51;*~", ESC_STR "[51;*~")}, /* F30 */ ! ! {TERMCAP2KEY('F', 'L'), IF_EB("\033[52;*~", ESC_STR "[52;*~")}, /* F31 */ ! {TERMCAP2KEY('F', 'M'), IF_EB("\033[53;*~", ESC_STR "[53;*~")}, /* F32 */ ! {TERMCAP2KEY('F', 'N'), IF_EB("\033[54;*~", ESC_STR "[54;*~")}, /* F33 */ ! {TERMCAP2KEY('F', 'O'), IF_EB("\033[55;*~", ESC_STR "[55;*~")}, /* F34 */ ! {TERMCAP2KEY('F', 'P'), IF_EB("\033[56;*~", ESC_STR "[56;*~")}, /* F35 */ ! {TERMCAP2KEY('F', 'Q'), IF_EB("\033[57;*~", ESC_STR "[57;*~")}, /* F36 */ ! {TERMCAP2KEY('F', 'R'), IF_EB("\033[58;*~", ESC_STR "[58;*~")}, /* F37 */ # endif # if defined(UNIX) || defined(ALL_BUILTIN_TCAPS) --- 978,1045 ---- {K_UNDO, IF_EB("\033[26;*~", ESC_STR "[26;*~")}, {K_INS, IF_EB("\033[2;*~", ESC_STR "[2;*~")}, {K_HOME, IF_EB("\033[1;*H", ESC_STR "[1;*H")}, ! // {K_S_HOME, IF_EB("\033O2H", ESC_STR "O2H")}, ! // {K_C_HOME, IF_EB("\033O5H", ESC_STR "O5H")}, {K_KHOME, IF_EB("\033[1;*~", ESC_STR "[1;*~")}, ! {K_XHOME, IF_EB("\033O*H", ESC_STR "O*H")}, // other Home ! {K_ZHOME, IF_EB("\033[7;*~", ESC_STR "[7;*~")}, // other Home {K_END, IF_EB("\033[1;*F", ESC_STR "[1;*F")}, ! // {K_S_END, IF_EB("\033O2F", ESC_STR "O2F")}, ! // {K_C_END, IF_EB("\033O5F", ESC_STR "O5F")}, {K_KEND, IF_EB("\033[4;*~", ESC_STR "[4;*~")}, ! {K_XEND, IF_EB("\033O*F", ESC_STR "O*F")}, // other End {K_ZEND, IF_EB("\033[8;*~", ESC_STR "[8;*~")}, {K_PAGEUP, IF_EB("\033[5;*~", ESC_STR "[5;*~")}, {K_PAGEDOWN, IF_EB("\033[6;*~", ESC_STR "[6;*~")}, ! {K_KPLUS, IF_EB("\033O*k", ESC_STR "O*k")}, // keypad plus ! {K_KMINUS, IF_EB("\033O*m", ESC_STR "O*m")}, // keypad minus ! {K_KDIVIDE, IF_EB("\033O*o", ESC_STR "O*o")}, // keypad / ! {K_KMULTIPLY, IF_EB("\033O*j", ESC_STR "O*j")}, // keypad * ! {K_KENTER, IF_EB("\033O*M", ESC_STR "O*M")}, // keypad Enter ! {K_KPOINT, IF_EB("\033O*n", ESC_STR "O*n")}, // keypad . ! {K_K0, IF_EB("\033O*p", ESC_STR "O*p")}, // keypad 0 ! {K_K1, IF_EB("\033O*q", ESC_STR "O*q")}, // keypad 1 ! {K_K2, IF_EB("\033O*r", ESC_STR "O*r")}, // keypad 2 ! {K_K3, IF_EB("\033O*s", ESC_STR "O*s")}, // keypad 3 ! {K_K4, IF_EB("\033O*t", ESC_STR "O*t")}, // keypad 4 ! {K_K5, IF_EB("\033O*u", ESC_STR "O*u")}, // keypad 5 ! {K_K6, IF_EB("\033O*v", ESC_STR "O*v")}, // keypad 6 ! {K_K7, IF_EB("\033O*w", ESC_STR "O*w")}, // keypad 7 ! {K_K8, IF_EB("\033O*x", ESC_STR "O*x")}, // keypad 8 ! {K_K9, IF_EB("\033O*y", ESC_STR "O*y")}, // keypad 9 ! {K_KDEL, IF_EB("\033[3;*~", ESC_STR "[3;*~")}, // keypad Del ! {K_PS, IF_EB("\033[200~", ESC_STR "[200~")}, // paste start ! {K_PE, IF_EB("\033[201~", ESC_STR "[201~")}, // paste end {BT_EXTRA_KEYS, ""}, ! {TERMCAP2KEY('k', '0'), IF_EB("\033[10;*~", ESC_STR "[10;*~")}, // F0 ! {TERMCAP2KEY('F', '3'), IF_EB("\033[25;*~", ESC_STR "[25;*~")}, // F13 ! // F14 and F15 are missing, because they send the same codes as the undo ! // and help key, although they don't work on all keyboards. ! {TERMCAP2KEY('F', '6'), IF_EB("\033[29;*~", ESC_STR "[29;*~")}, // F16 ! {TERMCAP2KEY('F', '7'), IF_EB("\033[31;*~", ESC_STR "[31;*~")}, // F17 ! {TERMCAP2KEY('F', '8'), IF_EB("\033[32;*~", ESC_STR "[32;*~")}, // F18 ! {TERMCAP2KEY('F', '9'), IF_EB("\033[33;*~", ESC_STR "[33;*~")}, // F19 ! {TERMCAP2KEY('F', 'A'), IF_EB("\033[34;*~", ESC_STR "[34;*~")}, // F20 ! ! {TERMCAP2KEY('F', 'B'), IF_EB("\033[42;*~", ESC_STR "[42;*~")}, // F21 ! {TERMCAP2KEY('F', 'C'), IF_EB("\033[43;*~", ESC_STR "[43;*~")}, // F22 ! {TERMCAP2KEY('F', 'D'), IF_EB("\033[44;*~", ESC_STR "[44;*~")}, // F23 ! {TERMCAP2KEY('F', 'E'), IF_EB("\033[45;*~", ESC_STR "[45;*~")}, // F24 ! {TERMCAP2KEY('F', 'F'), IF_EB("\033[46;*~", ESC_STR "[46;*~")}, // F25 ! {TERMCAP2KEY('F', 'G'), IF_EB("\033[47;*~", ESC_STR "[47;*~")}, // F26 ! {TERMCAP2KEY('F', 'H'), IF_EB("\033[48;*~", ESC_STR "[48;*~")}, // F27 ! {TERMCAP2KEY('F', 'I'), IF_EB("\033[49;*~", ESC_STR "[49;*~")}, // F28 ! {TERMCAP2KEY('F', 'J'), IF_EB("\033[50;*~", ESC_STR "[50;*~")}, // F29 ! {TERMCAP2KEY('F', 'K'), IF_EB("\033[51;*~", ESC_STR "[51;*~")}, // F30 ! ! {TERMCAP2KEY('F', 'L'), IF_EB("\033[52;*~", ESC_STR "[52;*~")}, // F31 ! {TERMCAP2KEY('F', 'M'), IF_EB("\033[53;*~", ESC_STR "[53;*~")}, // F32 ! {TERMCAP2KEY('F', 'N'), IF_EB("\033[54;*~", ESC_STR "[54;*~")}, // F33 ! {TERMCAP2KEY('F', 'O'), IF_EB("\033[55;*~", ESC_STR "[55;*~")}, // F34 ! {TERMCAP2KEY('F', 'P'), IF_EB("\033[56;*~", ESC_STR "[56;*~")}, // F35 ! {TERMCAP2KEY('F', 'Q'), IF_EB("\033[57;*~", ESC_STR "[57;*~")}, // F36 ! {TERMCAP2KEY('F', 'R'), IF_EB("\033[58;*~", ESC_STR "[58;*~")}, // F37 # endif # if defined(UNIX) || defined(ALL_BUILTIN_TCAPS) *************** *** 1061,1067 **** # else {(int)KS_CDL, "\033[%dM"}, # endif ! #if 0 /* The scroll region is not working as Vim expects. */ # ifdef TERMINFO {(int)KS_CS, "\033[%i%p1%d;%p2%dr"}, # else --- 1061,1067 ---- # else {(int)KS_CDL, "\033[%dM"}, # endif ! #if 0 // The scroll region is not working as Vim expects. # ifdef TERMINFO {(int)KS_CS, "\033[%i%p1%d;%p2%dr"}, # else *************** *** 1069,1076 **** # endif #endif {(int)KS_CL, "\033[H\033[2J"}, ! {(int)KS_VE, "\033[9/y\033[12/y"}, /* These aren't documented */ ! {(int)KS_VS, "\033[10/y\033[=1h\033[=2l"}, /* These aren't documented */ {(int)KS_TI, "\033[=6h"}, {(int)KS_TE, "\033[=6l"}, {(int)KS_SE, "\033[21;27m"}, --- 1069,1076 ---- # endif #endif {(int)KS_CL, "\033[H\033[2J"}, ! {(int)KS_VE, "\033[9/y\033[12/y"}, // These aren't documented ! {(int)KS_VS, "\033[10/y\033[=1h\033[=2l"}, // These aren't documented {(int)KS_TI, "\033[=6h"}, {(int)KS_TE, "\033[=6l"}, {(int)KS_SE, "\033[21;27m"}, *************** *** 1078,1101 **** {(int)KS_ME, "\033[m"}, {(int)KS_MR, "\033[7m"}, {(int)KS_MD, "\033[1m"}, ! {(int)KS_CCO, "8"}, /* allow 8 colors */ ! {(int)KS_CZH, "\033[3m"}, /* italic mode on */ ! {(int)KS_CZR, "\033[23m"}, /* italic mode off */ ! {(int)KS_US, "\033[4m"}, /* underline on */ ! {(int)KS_UE, "\033[24m"}, /* underline off */ ! # ifdef TERMINFO ! {(int)KS_CAB, "\033[4%p1%dm"}, /* set background color (ANSI) */ ! {(int)KS_CAF, "\033[3%p1%dm"}, /* set foreground color (ANSI) */ ! {(int)KS_CSB, "\033[102;%p1%dm"}, /* set screen background color */ ! {(int)KS_CSF, "\033[101;%p1%dm"}, /* set screen foreground color */ ! # else ! {(int)KS_CAB, "\033[4%dm"}, /* set background color (ANSI) */ ! {(int)KS_CAF, "\033[3%dm"}, /* set foreground color (ANSI) */ ! {(int)KS_CSB, "\033[102;%dm"}, /* set screen background color */ ! {(int)KS_CSF, "\033[101;%dm"}, /* set screen foreground color */ # endif ! {(int)KS_MS, "y"}, /* guessed */ ! {(int)KS_UT, "y"}, /* guessed */ {(int)KS_LE, "\b"}, # ifdef TERMINFO {(int)KS_CM, "\033[%i%p1%d;%p2%dH"}, --- 1078,1101 ---- {(int)KS_ME, "\033[m"}, {(int)KS_MR, "\033[7m"}, {(int)KS_MD, "\033[1m"}, ! {(int)KS_CCO, "8"}, // allow 8 colors ! {(int)KS_CZH, "\033[3m"}, // italic mode on ! {(int)KS_CZR, "\033[23m"}, // italic mode off ! {(int)KS_US, "\033[4m"}, // underline on ! {(int)KS_UE, "\033[24m"}, // underline off ! # ifdef TERMINFO ! {(int)KS_CAB, "\033[4%p1%dm"}, // set background color (ANSI) ! {(int)KS_CAF, "\033[3%p1%dm"}, // set foreground color (ANSI) ! {(int)KS_CSB, "\033[102;%p1%dm"}, // set screen background color ! {(int)KS_CSF, "\033[101;%p1%dm"}, // set screen foreground color ! # else ! {(int)KS_CAB, "\033[4%dm"}, // set background color (ANSI) ! {(int)KS_CAF, "\033[3%dm"}, // set foreground color (ANSI) ! {(int)KS_CSB, "\033[102;%dm"}, // set screen background color ! {(int)KS_CSF, "\033[101;%dm"}, // set screen foreground color # endif ! {(int)KS_MS, "y"}, // guessed ! {(int)KS_UT, "y"}, // guessed {(int)KS_LE, "\b"}, # ifdef TERMINFO {(int)KS_CM, "\033[%i%p1%d;%p2%dH"}, *************** *** 1109,1117 **** {(int)KS_CRI, "\033[%dC"}, # endif {(int)KS_CIS, "\033P3.y"}, ! {(int)KS_CIE, "\234"}, /* ST "String Terminator" */ {(int)KS_TS, "\033P1.y"}, ! {(int)KS_FS, "\234"}, /* ST "String Terminator" */ # ifdef TERMINFO {(int)KS_CWS, "\033[203;%p1%d;%p2%d/y"}, {(int)KS_CWP, "\033[205;%p1%d;%p2%d/y"}, --- 1109,1117 ---- {(int)KS_CRI, "\033[%dC"}, # endif {(int)KS_CIS, "\033P3.y"}, ! {(int)KS_CIE, "\234"}, // ST "String Terminator" {(int)KS_TS, "\033P1.y"}, ! {(int)KS_FS, "\234"}, // ST "String Terminator" # ifdef TERMINFO {(int)KS_CWS, "\033[203;%p1%d;%p2%d/y"}, {(int)KS_CWP, "\033[205;%p1%d;%p2%d/y"}, *************** *** 1342,1348 **** {K_K9, "[K9]"}, # endif ! #endif /* NO_BUILTIN_TCAPS */ /* * The most minimal terminal: only clear screen and cursor positioning --- 1342,1348 ---- {K_K9, "[K9]"}, # endif ! #endif // NO_BUILTIN_TCAPS /* * The most minimal terminal: only clear screen and cursor positioning *************** *** 1362,1368 **** */ {(int)KS_NAME, NULL} ! }; /* end of builtin_termcaps */ #if defined(FEAT_TERMGUICOLORS) || defined(PROTO) static guicolor_T --- 1362,1368 ---- */ {(int)KS_NAME, NULL} ! }; // end of builtin_termcaps #if defined(FEAT_TERMGUICOLORS) || defined(PROTO) static guicolor_T *************** *** 1431,1441 **** */ char_u *(term_strings[(int)KS_LAST + 1]); ! static int need_gather = FALSE; /* need to fill termleader[] */ ! static char_u termleader[256 + 1]; /* for check_termcode() */ #ifdef FEAT_TERMRESPONSE ! static int check_for_codes = FALSE; /* check for key code response */ ! static int is_not_xterm = FALSE; /* recognized not-really-xterm */ #endif static struct builtin_term * --- 1431,1441 ---- */ char_u *(term_strings[(int)KS_LAST + 1]); ! static int need_gather = FALSE; // need to fill termleader[] ! static char_u termleader[256 + 1]; // for check_termcode() #ifdef FEAT_TERMRESPONSE ! static int check_for_codes = FALSE; // check for key code response ! static int is_not_xterm = FALSE; // recognized not-really-xterm #endif static struct builtin_term * *************** *** 1483,1504 **** p = find_builtin_term(term); term_8bit = term_is_8bit(term); ! /* Do not parse if builtin term not found */ if (p->bt_string == NULL) return; for (++p; p->bt_entry != (int)KS_NAME && p->bt_entry != BT_EXTRA_KEYS; ++p) { ! if ((int)p->bt_entry >= 0) /* KS_xx entry */ { ! /* Only set the value if it wasn't set yet. */ if (term_strings[p->bt_entry] == NULL || term_strings[p->bt_entry] == empty_option) { #ifdef FEAT_EVAL int opt_idx = -1; #endif ! /* 8bit terminal: use CSI instead of [ */ if (term_8bit && term_7to8bit((char_u *)p->bt_string) != 0) { char_u *s, *t; --- 1483,1504 ---- p = find_builtin_term(term); term_8bit = term_is_8bit(term); ! // Do not parse if builtin term not found if (p->bt_string == NULL) return; for (++p; p->bt_entry != (int)KS_NAME && p->bt_entry != BT_EXTRA_KEYS; ++p) { ! if ((int)p->bt_entry >= 0) // KS_xx entry { ! // Only set the value if it wasn't set yet. if (term_strings[p->bt_entry] == NULL || term_strings[p->bt_entry] == empty_option) { #ifdef FEAT_EVAL int opt_idx = -1; #endif ! // 8bit terminal: use CSI instead of [ if (term_8bit && term_7to8bit((char_u *)p->bt_string) != 0) { char_u *s, *t; *************** *** 1550,1556 **** static void set_color_count(int nr) { ! char_u nr_colors[20]; /* string for number of colors */ t_colors = nr; if (t_colors > 1) --- 1550,1556 ---- static void set_color_count(int nr) { ! char_u nr_colors[20]; // string for number of colors t_colors = nr; if (t_colors > 1) *************** *** 1569,1578 **** { if (val != t_colors) { ! /* Nr of colors changed, initialize highlighting and ! * redraw everything. This causes a redraw, which usually ! * clears the message. Try keeping the message if it ! * might work. */ set_keep_msg_from_hist(); set_color_count(val); init_highlight(TRUE, FALSE); --- 1569,1578 ---- { if (val != t_colors) { ! // Nr of colors changed, initialize highlighting and ! // redraw everything. This causes a redraw, which usually ! // clears the message. Try keeping the message if it ! // might work. set_keep_msg_from_hist(); set_color_count(val); init_highlight(TRUE, FALSE); *************** *** 1593,1599 **** static char *(key_names[]) = { #ifdef FEAT_TERMRESPONSE ! /* Do this one first, it may cause a screen redraw. */ "Co", #endif "ku", "kd", "kr", "kl", --- 1593,1599 ---- static char *(key_names[]) = { #ifdef FEAT_TERMRESPONSE ! // Do this one first, it may cause a screen redraw. "Co", #endif "ku", "kd", "kr", "kl", *************** *** 1611,1618 **** get_term_entries(int *height, int *width) { static struct { ! enum SpecialKey dest; /* index in term_strings[] */ ! char *name; /* termcap name for string */ } string_names[] = { {KS_CE, "ce"}, {KS_AL, "al"}, {KS_CAL,"AL"}, {KS_DL, "dl"}, {KS_CDL,"DL"}, {KS_CS, "cs"}, --- 1611,1618 ---- get_term_entries(int *height, int *width) { static struct { ! enum SpecialKey dest; // index in term_strings[] ! char *name; // termcap name for string } string_names[] = { {KS_CE, "ce"}, {KS_AL, "al"}, {KS_CAL,"AL"}, {KS_DL, "dl"}, {KS_CDL,"DL"}, {KS_CS, "cs"}, *************** *** 1664,1671 **** } } ! /* tgetflag() returns 1 if the flag is present, 0 if not and ! * possibly -1 if the flag doesn't exist. */ if ((T_MS == NULL || T_MS == empty_option) && tgetflag("ms") > 0) T_MS = (char_u *)"y"; if ((T_XS == NULL || T_XS == empty_option) && tgetflag("xs") > 0) --- 1664,1671 ---- } } ! // tgetflag() returns 1 if the flag is present, 0 if not and ! // possibly -1 if the flag doesn't exist. if ((T_MS == NULL || T_MS == empty_option) && tgetflag("ms") > 0) T_MS = (char_u *)"y"; if ((T_XS == NULL || T_XS == empty_option) && tgetflag("xs") > 0) *************** *** 1686,1692 **** if (find_termcode((char_u *)key_names[i]) == NULL) { p = TGETSTR(key_names[i], &tp); ! /* if cursor-left == backspace, ignore it (televideo 925) */ if (p != NULL && (*p != Ctrl_H || key_names[i][0] != 'k' --- 1686,1692 ---- if (find_termcode((char_u *)key_names[i]) == NULL) { p = TGETSTR(key_names[i], &tp); ! // if cursor-left == backspace, ignore it (televideo 925) if (p != NULL && (*p != Ctrl_H || key_names[i][0] != 'k' *************** *** 1758,1764 **** mch_errmsg("'\r\n"); if (emsg_silent == 0) { ! screen_start(); /* don't know where cursor is now */ out_flush(); if (!is_not_a_term()) ui_delay(2007L, TRUE); --- 1758,1764 ---- mch_errmsg("'\r\n"); if (emsg_silent == 0) { ! screen_start(); // don't know where cursor is now out_flush(); if (!is_not_a_term()) ui_delay(2007L, TRUE); *************** *** 1784,1794 **** char *error_msg = NULL; char_u *bs_p, *del_p; ! /* In silect mode (ex -s) we don't use the 'term' option. */ if (silent_mode) return OK; ! detected_8bit = FALSE; /* reset 8-bit detection */ if (term_is_builtin(term)) { --- 1784,1794 ---- char *error_msg = NULL; char_u *bs_p, *del_p; ! // In silect mode (ex -s) we don't use the 'term' option. if (silent_mode) return OK; ! detected_8bit = FALSE; // reset 8-bit detection if (term_is_builtin(term)) { *************** *** 1826,1840 **** { if (!termcap_cleared) { ! clear_termoptions(); /* clear old options */ termcap_cleared = TRUE; } get_term_entries(&height, &width); } } ! else /* try == 0 || try == 2 */ ! #endif /* HAVE_TGETENT */ /* * Use builtin termcap */ --- 1826,1840 ---- { if (!termcap_cleared) { ! clear_termoptions(); // clear old options termcap_cleared = TRUE; } get_term_entries(&height, &width); } } ! else // try == 0 || try == 2 ! #endif // HAVE_TGETENT /* * Use builtin termcap */ *************** *** 1851,1857 **** * search for 'term' in builtin_termcaps[] */ termp = find_builtin_term(term); ! if (termp->bt_string == NULL) /* did not find it */ { #ifdef HAVE_TGETENT /* --- 1851,1857 ---- * search for 'term' in builtin_termcaps[] */ termp = find_builtin_term(term); ! if (termp->bt_string == NULL) // did not find it { #ifdef HAVE_TGETENT /* *************** *** 1861,1877 **** * don't complain about not finding the term in the builtin * termcap. */ ! if (try == 0) /* try external one */ continue; ! if (termcap_cleared) /* found in external termcap */ break; #endif report_term_error(error_msg, term); ! /* when user typed :set term=xxx, quit here */ if (starting != NO_SCREEN) { ! screen_start(); /* don't know where cursor is now */ wait_return(TRUE); return FAIL; } --- 1861,1877 ---- * don't complain about not finding the term in the builtin * termcap. */ ! if (try == 0) // try external one continue; ! if (termcap_cleared) // found in external termcap break; #endif report_term_error(error_msg, term); ! // when user typed :set term=xxx, quit here if (starting != NO_SCREEN) { ! screen_start(); // don't know where cursor is now wait_return(TRUE); return FAIL; } *************** *** 1886,1892 **** if (!termcap_cleared) { #endif ! clear_termoptions(); /* clear old options */ #ifdef HAVE_TGETENT termcap_cleared = TRUE; } --- 1886,1892 ---- if (!termcap_cleared) { #endif ! clear_termoptions(); // clear old options #ifdef HAVE_TGETENT termcap_cleared = TRUE; } *************** *** 1897,1911 **** { out_flush(); gui_init(); ! /* If starting the GUI failed, don't do any of the other ! * things for this terminal */ if (!gui.in_use) return FAIL; #ifdef HAVE_TGETENT ! break; /* don't try using external termcap */ #endif } ! #endif /* FEAT_GUI */ } #ifdef HAVE_TGETENT } --- 1897,1911 ---- { out_flush(); gui_init(); ! // If starting the GUI failed, don't do any of the other ! // things for this terminal if (!gui.in_use) return FAIL; #ifdef HAVE_TGETENT ! break; // don't try using external termcap #endif } ! #endif // FEAT_GUI } #ifdef HAVE_TGETENT } *************** *** 1976,1982 **** if (use_xterm_like_mouse(term)) { if (use_xterm_mouse()) ! p = NULL; /* keep existing value, might be "xterm2" */ else p = (char_u *)"xterm"; } --- 1976,1982 ---- if (use_xterm_like_mouse(term)) { if (use_xterm_mouse()) ! p = NULL; // keep existing value, might be "xterm2" else p = (char_u *)"xterm"; } *************** *** 1984,1991 **** if (p != NULL) { set_option_value((char_u *)"ttym", 0L, p, 0); ! /* Reset the WAS_SET flag, 'ttymouse' can be set to "sgr" or ! * "xterm2" in check_termcode(). */ reset_option_was_set((char_u *)"ttym"); } if (p == NULL --- 1984,1991 ---- if (p != NULL) { set_option_value((char_u *)"ttym", 0L, p, 0); ! // Reset the WAS_SET flag, 'ttymouse' can be set to "sgr" or ! // "xterm2" in check_termcode(). reset_option_was_set((char_u *)"ttym"); } if (p == NULL *************** *** 1993,2013 **** || gui.in_use # endif ) ! check_mouse_termcode(); /* set mouse termcode anyway */ } #else set_mouse_termcode(KS_MOUSE, (char_u *)"\233M"); #endif #ifdef USE_TERM_CONSOLE ! /* DEFAULT_TERM indicates that it is the machine console. */ if (STRCMP(term, DEFAULT_TERM) != 0) term_console = FALSE; else { term_console = TRUE; # ifdef AMIGA ! win_resize_on(); /* enable window resizing reports */ # endif } #endif --- 1993,2013 ---- || gui.in_use # endif ) ! check_mouse_termcode(); // set mouse termcode anyway } #else set_mouse_termcode(KS_MOUSE, (char_u *)"\233M"); #endif #ifdef USE_TERM_CONSOLE ! // DEFAULT_TERM indicates that it is the machine console. if (STRCMP(term, DEFAULT_TERM) != 0) term_console = FALSE; else { term_console = TRUE; # ifdef AMIGA ! win_resize_on(); // enable window resizing reports # endif } #endif *************** *** 2027,2036 **** p_tf = TRUE; #endif ! ttest(TRUE); /* make sure we have a valid set of terminal codes */ ! full_screen = TRUE; /* we can use termcap codes from now on */ ! set_term_defaults(); /* use current values as defaults */ #ifdef FEAT_TERMRESPONSE LOG_TR(("setting crv_status to STATUS_GET")); crv_status.tr_progress = STATUS_GET; // Get terminal version later --- 2027,2036 ---- p_tf = TRUE; #endif ! ttest(TRUE); // make sure we have a valid set of terminal codes ! full_screen = TRUE; // we can use termcap codes from now on ! set_term_defaults(); // use current values as defaults #ifdef FEAT_TERMRESPONSE LOG_TR(("setting crv_status to STATUS_GET")); crv_status.tr_progress = STATUS_GET; // Get terminal version later *************** *** 2044,2074 **** */ if (starting != NO_SCREEN) { ! starttermcap(); /* may change terminal mode */ ! setmouse(); /* may start using the mouse */ #ifdef FEAT_TITLE ! maketitle(); /* may display window title */ #endif } ! /* display initial screen after ttest() checking. jw. */ if (width <= 0 || height <= 0) { ! /* termcap failed to report size */ ! /* set defaults, in case ui_get_shellsize() also fails */ width = 80; #if defined(MSWIN) ! height = 25; /* console is often 25 lines */ #else ! height = 24; /* most terminals are 24 lines */ #endif } ! set_shellsize(width, height, FALSE); /* may change Rows */ if (starting != NO_SCREEN) { if (scroll_region) ! scroll_region_reset(); /* In case Rows changed */ ! check_map_keycodes(); /* check mappings for terminal codes used */ { bufref_T old_curbuf; --- 2044,2074 ---- */ if (starting != NO_SCREEN) { ! starttermcap(); // may change terminal mode ! setmouse(); // may start using the mouse #ifdef FEAT_TITLE ! maketitle(); // may display window title #endif } ! // display initial screen after ttest() checking. jw. if (width <= 0 || height <= 0) { ! // termcap failed to report size ! // set defaults, in case ui_get_shellsize() also fails width = 80; #if defined(MSWIN) ! height = 25; // console is often 25 lines #else ! height = 24; // most terminals are 24 lines #endif } ! set_shellsize(width, height, FALSE); // may change Rows if (starting != NO_SCREEN) { if (scroll_region) ! scroll_region_reset(); // In case Rows changed ! check_map_keycodes(); // check mappings for terminal codes used { bufref_T old_curbuf; *************** *** 2107,2121 **** int i; i = TGETENT(tbuf, term); ! if (i < 0 /* -1 is always an error */ # ifdef TGETENT_ZERO_ERR ! || i == 0 /* sometimes zero is also an error */ # endif ) { ! /* On FreeBSD tputs() gets a SEGV after a tgetent() which fails. Call ! * tgetent() with the always existing "dumb" entry to avoid a crash or ! * hang. */ (void)TGETENT(tbuf, "dumb"); if (i < 0) --- 2107,2121 ---- int i; i = TGETENT(tbuf, term); ! if (i < 0 // -1 is always an error # ifdef TGETENT_ZERO_ERR ! || i == 0 // sometimes zero is also an error # endif ) { ! // On FreeBSD tputs() gets a SEGV after a tgetent() which fails. Call ! // tgetent() with the always existing "dumb" entry to avoid a crash or ! // hang. (void)TGETENT(tbuf, "dumb"); if (i < 0) *************** *** 2146,2152 **** p = NULL; return (char_u *)p; } ! #endif /* HAVE_TGETENT */ #if defined(HAVE_TGETENT) && (defined(UNIX) || defined(VMS) || defined(MACOS_X)) /* --- 2146,2152 ---- p = NULL; return (char_u *)p; } ! #endif // HAVE_TGETENT #if defined(HAVE_TGETENT) && (defined(UNIX) || defined(VMS) || defined(MACOS_X)) /* *************** *** 2157,2164 **** */ void getlinecol( ! long *cp, /* pointer to columns */ ! long *rp) /* pointer to rows */ { char_u tbuf[TBUFSZ]; --- 2157,2164 ---- */ void getlinecol( ! long *cp, // pointer to columns ! long *rp) // pointer to rows { char_u tbuf[TBUFSZ]; *************** *** 2170,2176 **** *rp = tgetnum("li"); } } ! #endif /* defined(HAVE_TGETENT) && defined(UNIX) */ /* * Get a string entry from the termcap and add it to the list of termcodes. --- 2170,2176 ---- *rp = tgetnum("li"); } } ! #endif // defined(HAVE_TGETENT) && defined(UNIX) /* * Get a string entry from the termcap and add it to the list of termcodes. *************** *** 2204,2217 **** return gui_mch_haskey(name); #endif ! if (!force && find_termcode(name) != NULL) /* it's already there */ return OK; term = T_NAME; ! if (term == NULL || *term == NUL) /* 'term' not defined yet */ return FAIL; ! if (term_is_builtin(term)) /* name starts with "builtin_" */ { term += 8; #ifdef HAVE_TGETENT --- 2204,2217 ---- return gui_mch_haskey(name); #endif ! if (!force && find_termcode(name) != NULL) // it's already there return OK; term = T_NAME; ! if (term == NULL || *term == NUL) // 'term' not defined yet return FAIL; ! if (term_is_builtin(term)) // name starts with "builtin_" { term += 8; #ifdef HAVE_TGETENT *************** *** 2239,2245 **** */ { termp = find_builtin_term(term); ! if (termp->bt_string != NULL) /* found it */ { key = TERMCAP2KEY(name[0], name[1]); ++termp; --- 2239,2245 ---- */ { termp = find_builtin_term(term); ! if (termp->bt_string != NULL) // found it { key = TERMCAP2KEY(name[0], name[1]); ++termp; *************** *** 2403,2409 **** return buf; } ! #endif /* HAVE_TGETENT */ /* * Set the terminal name and initialize the terminal options. --- 2403,2409 ---- return buf; } ! #endif // HAVE_TGETENT /* * Set the terminal name and initialize the terminal options. *************** *** 2416,2422 **** char_u *term; if (name != NULL && *name == NUL) ! name = NULL; /* empty name is equal to no name */ term = name; #ifdef __BEOS__ --- 2416,2422 ---- char_u *term; if (name != NULL && *name == NUL) ! name = NULL; // empty name is equal to no name term = name; #ifdef __BEOS__ *************** *** 2438,2444 **** term = DEFAULT_TERM; set_string_option_direct((char_u *)"term", -1, term, OPT_FREE, 0); ! /* Set the default terminal name. */ set_string_default("term", term); set_string_default("ttytype", term); --- 2438,2444 ---- term = DEFAULT_TERM; set_string_option_direct((char_u *)"term", -1, term, OPT_FREE, 0); ! // Set the default terminal name. set_string_default("term", term); set_string_default("ttytype", term); *************** *** 2472,2478 **** if (out_pos != 0) { ! /* set out_pos to 0 before ui_write, to avoid recursiveness */ len = out_pos; out_pos = 0; ui_write(out_buf, len); --- 2472,2478 ---- if (out_pos != 0) { ! // set out_pos to 0 before ui_write, to avoid recursiveness len = out_pos; out_pos = 0; ui_write(out_buf, len); *************** *** 2485,2492 **** */ void out_flush_cursor( ! int force UNUSED, /* when TRUE, update cursor even when not moved */ ! int clear_selection UNUSED) /* clear selection under cursor */ { mch_disable_flush(); out_flush(); --- 2485,2492 ---- */ void out_flush_cursor( ! int force UNUSED, // when TRUE, update cursor even when not moved ! int clear_selection UNUSED) // clear selection under cursor { mch_disable_flush(); out_flush(); *************** *** 2533,2545 **** out_char(unsigned c) { #if defined(UNIX) || defined(VMS) || defined(AMIGA) || defined(MACOS_X) ! if (c == '\n') /* turn LF into CR-LF (CRMOD doesn't seem to do this) */ out_char('\r'); #endif out_buf[out_pos++] = c; ! /* For testing we flush each time. */ if (out_pos >= OUT_SIZE || p_wd) out_flush(); } --- 2533,2545 ---- out_char(unsigned c) { #if defined(UNIX) || defined(VMS) || defined(AMIGA) || defined(MACOS_X) ! if (c == '\n') // turn LF into CR-LF (CRMOD doesn't seem to do this) out_char('\r'); #endif out_buf[out_pos++] = c; ! // For testing we flush each time. if (out_pos >= OUT_SIZE || p_wd) out_flush(); } *************** *** 2596,2602 **** #endif #ifdef FEAT_GUI ! /* Don't use tputs() when GUI is used, ncurses crashes. */ if (gui.in_use) { out_str_nf(s); --- 2596,2602 ---- #endif #ifdef FEAT_GUI ! // Don't use tputs() when GUI is used, ncurses crashes. if (gui.in_use) { out_str_nf(s); *************** *** 2608,2614 **** #ifdef HAVE_TGETENT for (p = s; *s; ++s) { ! /* flush just before delay command */ if (*s == '$' && *(s + 1) == '<') { char_u save_c = *s; --- 2608,2614 ---- #ifdef HAVE_TGETENT for (p = s; *s; ++s) { ! // flush just before delay command if (*s == '$' && *(s + 1) == '<') { char_u save_c = *s; *************** *** 2619,2630 **** *s = save_c; out_flush(); # ifdef ELAPSED_FUNC ! /* Only sleep here if we can limit this happening in ! * vim_beep(). */ p = vim_strchr(s, '>'); if (p == NULL || duration <= 0) { ! /* can't parse the time, don't sleep here */ p = s; } else --- 2619,2630 ---- *s = save_c; out_flush(); # ifdef ELAPSED_FUNC ! // Only sleep here if we can limit this happening in ! // vim_beep(). p = vim_strchr(s, '>'); if (p == NULL || duration <= 0) { ! // can't parse the time, don't sleep here p = s; } else *************** *** 2633,2639 **** do_sleep(duration); } # else ! /* Rely on the terminal library to sleep. */ p = s; # endif break; --- 2633,2639 ---- do_sleep(duration); } # else ! // Rely on the terminal library to sleep. p = s; # endif break; *************** *** 2645,2651 **** out_char_nf(*s++); #endif ! /* For testing we write one string at a time. */ if (p_wd) out_flush(); } --- 2645,2651 ---- out_char_nf(*s++); #endif ! // For testing we write one string at a time. if (p_wd) out_flush(); } *************** *** 2663,2676 **** if (s != NULL && *s) { #ifdef FEAT_GUI ! /* Don't use tputs() when GUI is used, ncurses crashes. */ if (gui.in_use) { out_str_nf(s); return; } #endif ! /* avoid terminal strings being split up */ if (out_pos > OUT_SIZE - MAX_ESC_SEQ_LEN) out_flush(); #ifdef HAVE_TGETENT --- 2663,2676 ---- if (s != NULL && *s) { #ifdef FEAT_GUI ! // Don't use tputs() when GUI is used, ncurses crashes. if (gui.in_use) { out_str_nf(s); return; } #endif ! // avoid terminal strings being split up if (out_pos > OUT_SIZE - MAX_ESC_SEQ_LEN) out_flush(); #ifdef HAVE_TGETENT *************** *** 2680,2686 **** out_char_nf(*s++); #endif ! /* For testing we write one string at a time. */ if (p_wd) out_flush(); } --- 2680,2686 ---- out_char_nf(*s++); #endif ! // For testing we write one string at a time. if (p_wd) out_flush(); } *************** *** 2717,2723 **** void term_set_winpos(int x, int y) { ! /* Can't handle a negative value here */ if (x < 0) x = 0; if (y < 0) --- 2717,2723 ---- void term_set_winpos(int x, int y) { ! // Can't handle a negative value here if (x < 0) x = 0; if (y < 0) *************** *** 2800,2806 **** OUT_STR(T_CGP); out_flush(); ! /* Try reading the result for "timeout" msec. */ while (count++ <= timeout / 10 && !got_int) { (void)vpeekc_nomap(); --- 2800,2806 ---- OUT_STR(T_CGP); out_flush(); ! // Try reading the result for "timeout" msec. while (count++ <= timeout / 10 && !got_int) { (void)vpeekc_nomap(); *************** *** 2812,2825 **** } ui_delay(10L, FALSE); } ! /* Do not reset "did_request_winpos", if we timed out the response might ! * still come later and we must consume it. */ winpos_x = prev_winpos_x; winpos_y = prev_winpos_y; if (timeout < 10 && prev_winpos_y >= 0 && prev_winpos_x >= 0) { ! /* Polling: return previous values if we have them. */ *x = winpos_x; *y = winpos_y; return OK; --- 2812,2825 ---- } ui_delay(10L, FALSE); } ! // Do not reset "did_request_winpos", if we timed out the response might ! // still come later and we must consume it. winpos_x = prev_winpos_x; winpos_y = prev_winpos_y; if (timeout < 10 && prev_winpos_y >= 0 && prev_winpos_x >= 0) { ! // Polling: return previous values if we have them. *x = winpos_x; *y = winpos_y; return OK; *************** *** 2842,2852 **** { char buf[20]; int i = *s == CSI ? 1 : 2; ! /* index in s[] just after [ or CSI */ ! /* Special handling of 16 colors, because termcap can't handle it */ ! /* Also accept "\e[3%dm" for TERMINFO, it is sometimes used */ ! /* Also accept CSI instead of [ */ if (n >= 8 && t_colors >= 16 && ((s[0] == ESC && s[1] == '[') #if defined(FEAT_VTP) && defined(FEAT_TERMGUICOLORS) --- 2842,2852 ---- { char buf[20]; int i = *s == CSI ? 1 : 2; ! // index in s[] just after [ or CSI ! // Special handling of 16 colors, because termcap can't handle it ! // Also accept "\e[3%dm" for TERMINFO, it is sometimes used ! // Also accept CSI instead of [ if (n >= 8 && t_colors >= 16 && ((s[0] == ESC && s[1] == '[') #if defined(FEAT_VTP) && defined(FEAT_TERMGUICOLORS) *************** *** 2881,2887 **** void term_fg_color(int n) { ! /* Use "AF" termcap entry if present, "Sf" entry otherwise */ if (*T_CAF) term_color(T_CAF, n); else if (*T_CSF) --- 2881,2887 ---- void term_fg_color(int n) { ! // Use "AF" termcap entry if present, "Sf" entry otherwise if (*T_CAF) term_color(T_CAF, n); else if (*T_CSF) *************** *** 2891,2897 **** void term_bg_color(int n) { ! /* Use "AB" termcap entry if present, "Sb" entry otherwise */ if (*T_CAB) term_color(T_CAB, n); else if (*T_CSB) --- 2891,2897 ---- void term_bg_color(int n) { ! // Use "AB" termcap entry if present, "Sb" entry otherwise if (*T_CAB) term_color(T_CAB, n); else if (*T_CSB) *************** *** 2914,2920 **** term_bg_default(void) { #if defined(MSWIN) ! /* DOS console is nearly always black */ return (char_u *)"dark"; #else char_u *p; --- 2914,2920 ---- term_bg_default(void) { #if defined(MSWIN) ! // DOS console is nearly always black return (char_u *)"dark"; #else char_u *p; *************** *** 3026,3032 **** { char_u *env_colors; ! check_options(); /* make sure no options are NULL */ /* * MUST have "cm": cursor motion. --- 3026,3032 ---- { char_u *env_colors; ! check_options(); // make sure no options are NULL /* * MUST have "cm": cursor motion. *************** *** 3047,3053 **** /* * optional pairs */ ! /* TP goes to normal mode for TI (invert) and TB (bold) */ if (*T_ME == NUL) T_ME = T_MR = T_MD = T_MB = empty_option; if (*T_SO == NUL || *T_SE == NUL) --- 3047,3053 ---- /* * optional pairs */ ! // TP goes to normal mode for TI (invert) and TB (bold) if (*T_ME == NUL) T_ME = T_MR = T_MD = T_MB = empty_option; if (*T_SO == NUL || *T_SE == NUL) *************** *** 3057,3067 **** if (*T_CZH == NUL || *T_CZR == NUL) T_CZH = T_CZR = empty_option; ! /* T_VE is needed even though T_VI is not defined */ if (*T_VE == NUL) T_VI = empty_option; ! /* if 'mr' or 'me' is not defined use 'so' and 'se' */ if (*T_ME == NUL) { T_ME = T_SE; --- 3057,3067 ---- if (*T_CZH == NUL || *T_CZR == NUL) T_CZH = T_CZR = empty_option; ! // T_VE is needed even though T_VI is not defined if (*T_VE == NUL) T_VI = empty_option; ! // if 'mr' or 'me' is not defined use 'so' and 'se' if (*T_ME == NUL) { T_ME = T_SE; *************** *** 3069,3075 **** T_MD = T_SO; } ! /* if 'so' or 'se' is not defined use 'mr' and 'me' */ if (*T_SO == NUL) { T_SE = T_ME; --- 3069,3075 ---- T_MD = T_SO; } ! // if 'so' or 'se' is not defined use 'mr' and 'me' if (*T_SO == NUL) { T_SE = T_ME; *************** *** 3079,3085 **** T_SO = T_MR; } ! /* if 'ZH' or 'ZR' is not defined use 'mr' and 'me' */ if (*T_CZH == NUL) { T_CZR = T_ME; --- 3079,3085 ---- T_SO = T_MR; } ! // if 'ZH' or 'ZR' is not defined use 'mr' and 'me' if (*T_CZH == NUL) { T_CZR = T_ME; *************** *** 3089,3118 **** T_CZH = T_MR; } ! /* "Sb" and "Sf" come in pairs */ if (*T_CSB == NUL || *T_CSF == NUL) { T_CSB = empty_option; T_CSF = empty_option; } ! /* "AB" and "AF" come in pairs */ if (*T_CAB == NUL || *T_CAF == NUL) { T_CAB = empty_option; T_CAF = empty_option; } ! /* if 'Sb' and 'AB' are not defined, reset "Co" */ if (*T_CSB == NUL && *T_CAB == NUL) free_one_termoption(T_CCO); ! /* Set 'weirdinvert' according to value of 't_xs' */ p_wiv = (*T_XS != NUL); } need_gather = TRUE; ! /* Set t_colors to the value of $COLORS or t_Co. */ t_colors = atoi((char *)T_CCO); env_colors = mch_getenv((char_u *)"COLORS"); if (env_colors != NULL && isdigit(*env_colors)) --- 3089,3118 ---- T_CZH = T_MR; } ! // "Sb" and "Sf" come in pairs if (*T_CSB == NUL || *T_CSF == NUL) { T_CSB = empty_option; T_CSF = empty_option; } ! // "AB" and "AF" come in pairs if (*T_CAB == NUL || *T_CAF == NUL) { T_CAB = empty_option; T_CAF = empty_option; } ! // if 'Sb' and 'AB' are not defined, reset "Co" if (*T_CSB == NUL && *T_CAB == NUL) free_one_termoption(T_CCO); ! // Set 'weirdinvert' according to value of 't_xs' p_wiv = (*T_XS != NUL); } need_gather = TRUE; ! // Set t_colors to the value of $COLORS or t_Co. t_colors = atoi((char *)T_CCO); env_colors = mch_getenv((char_u *)"COLORS"); if (env_colors != NULL && isdigit(*env_colors)) *************** *** 3192,3210 **** return -1; if (c == K_SPECIAL) { ! if (buf[len] == NUL || buf[len + 1] == NUL) /* cannot happen? */ return -1; if (buf[len++] == (int)KS_ZERO) c = NUL; ! /* else it should be KS_SPECIAL; when followed by KE_FILLER c is ! * K_SPECIAL, or followed by KE_CSI and c must be CSI. */ if (buf[len++] == (int)KE_CSI) c = CSI; } else if (c == CSI && buf[len] == KS_EXTRA && buf[len + 1] == (int)KE_CSI) ! /* CSI is stored as CSI KS_SPECIAL KE_CSI to avoid confusion with ! * the start of a special key, see add_to_input_buf_csi(). */ len += 2; bytes[i] = c; } --- 3192,3210 ---- return -1; if (c == K_SPECIAL) { ! if (buf[len] == NUL || buf[len + 1] == NUL) // cannot happen? return -1; if (buf[len++] == (int)KS_ZERO) c = NUL; ! // else it should be KS_SPECIAL; when followed by KE_FILLER c is ! // K_SPECIAL, or followed by KE_CSI and c must be CSI. if (buf[len++] == (int)KE_CSI) c = CSI; } else if (c == CSI && buf[len] == KS_EXTRA && buf[len + 1] == (int)KE_CSI) ! // CSI is stored as CSI KS_SPECIAL KE_CSI to avoid confusion with ! // the start of a special key, see add_to_input_buf_csi(). len += 2; bytes[i] = c; } *************** *** 3218,3224 **** void check_shellsize(void) { ! if (Rows < min_rows()) /* need room for one window and command line */ Rows = min_rows(); limit_screen_size(); } --- 3218,3224 ---- void check_shellsize(void) { ! if (Rows < min_rows()) // need room for one window and command line Rows = min_rows(); limit_screen_size(); } *************** *** 3250,3265 **** ui_new_shellsize(); if (old_Rows != Rows) { ! /* if 'window' uses the whole screen, keep it using that */ if (p_window == old_Rows - 1 || old_Rows == 0) p_window = Rows - 1; old_Rows = Rows; ! shell_new_rows(); /* update window sizes */ } if (old_Columns != Columns) { old_Columns = Columns; ! shell_new_columns(); /* update window sizes */ } } --- 3250,3265 ---- ui_new_shellsize(); if (old_Rows != Rows) { ! // if 'window' uses the whole screen, keep it using that if (p_window == old_Rows - 1 || old_Rows == 0) p_window = Rows - 1; old_Rows = Rows; ! shell_new_rows(); // update window sizes } if (old_Columns != Columns) { old_Columns = Columns; ! shell_new_columns(); // update window sizes } } *************** *** 3285,3292 **** if (!exiting #ifdef FEAT_GUI ! /* Do not get the size when executing a shell command during ! * startup. */ && !gui.starting #endif ) --- 3285,3292 ---- if (!exiting #ifdef FEAT_GUI ! // Do not get the size when executing a shell command during ! // startup. && !gui.starting #endif ) *************** *** 3317,3323 **** if (busy) return; ! if (width < 0 || height < 0) /* just checking... */ return; if (State == HITRETURN || State == SETWSIZE) --- 3317,3323 ---- if (busy) return; ! if (width < 0 || height < 0) // just checking... return; if (State == HITRETURN || State == SETWSIZE) *************** *** 3331,3348 **** // resizing while in update_screen() may cause a crash return; ! /* curwin->w_buffer can be NULL when we are closing a window and the ! * buffer has already been closed and removing a scrollbar causes a resize ! * event. Don't resize then, it will happen after entering another buffer. ! */ if (curwin->w_buffer == NULL) return; ++busy; #ifdef AMIGA ! out_flush(); /* must do this before mch_get_shellsize() for ! some obscure reason */ #endif if (mustset || (ui_get_shellsize() == FAIL && height != 0)) --- 3331,3347 ---- // resizing while in update_screen() may cause a crash return; ! // curwin->w_buffer can be NULL when we are closing a window and the ! // buffer has already been closed and removing a scrollbar causes a resize ! // event. Don't resize then, it will happen after entering another buffer. if (curwin->w_buffer == NULL) return; ++busy; #ifdef AMIGA ! out_flush(); // must do this before mch_get_shellsize() for ! // some obscure reason #endif if (mustset || (ui_get_shellsize() == FAIL && height != 0)) *************** *** 3355,3368 **** else check_shellsize(); ! /* The window layout used to be adjusted here, but it now happens in ! * screenalloc() (also invoked from screenclear()). That is because the ! * "busy" check above may skip this, but not screenalloc(). */ if (State != ASKMORE && State != EXTERNCMD && State != CONFIRM) screenclear(); else ! screen_start(); /* don't know where cursor is now */ if (starting != NO_SCREEN) { --- 3354,3367 ---- else check_shellsize(); ! // The window layout used to be adjusted here, but it now happens in ! // screenalloc() (also invoked from screenclear()). That is because the ! // "busy" check above may skip this, but not screenalloc(). if (State != ASKMORE && State != EXTERNCMD && State != CONFIRM) screenclear(); else ! screen_start(); // don't know where cursor is now if (starting != NO_SCREEN) { *************** *** 3410,3416 **** setcursor(); } } ! cursor_on(); /* redrawing may have switched it off */ } out_flush(); --busy; --- 3409,3415 ---- setcursor(); } } ! cursor_on(); // redrawing may have switched it off } out_flush(); --busy; *************** *** 3424,3430 **** settmode(int tmode) { #ifdef FEAT_GUI ! /* don't set the term where gvim was started to any mode */ if (gui.in_use) return; #endif --- 3423,3429 ---- settmode(int tmode) { #ifdef FEAT_GUI ! // don't set the term where gvim was started to any mode if (gui.in_use) return; #endif *************** *** 3482,3502 **** { if (full_screen && !termcap_active) { ! out_str(T_TI); /* start termcap mode */ ! out_str(T_CTI); /* start "raw" mode */ ! out_str(T_KS); /* start "keypad transmit" mode */ ! out_str(T_BE); /* enable bracketed paste mode */ out_flush(); termcap_active = TRUE; ! screen_start(); /* don't know where cursor is now */ #ifdef FEAT_TERMRESPONSE # ifdef FEAT_GUI if (!gui.in_use && !gui.starting) # endif { may_req_termresponse(); ! /* Immediately check for a response. If t_Co changes, we don't ! * want to redraw with wrong colors first. */ if (crv_status.tr_progress == STATUS_SENT) check_for_codes_from_term(); } --- 3481,3501 ---- { if (full_screen && !termcap_active) { ! out_str(T_TI); // start termcap mode ! out_str(T_CTI); // start "raw" mode ! out_str(T_KS); // start "keypad transmit" mode ! out_str(T_BE); // enable bracketed paste mode out_flush(); termcap_active = TRUE; ! screen_start(); // don't know where cursor is now #ifdef FEAT_TERMRESPONSE # ifdef FEAT_GUI if (!gui.in_use && !gui.starting) # endif { may_req_termresponse(); ! // Immediately check for a response. If t_Co changes, we don't ! // want to redraw with wrong colors first. if (crv_status.tr_progress == STATUS_SENT) check_for_codes_from_term(); } *************** *** 3529,3547 **** tcflush(fileno(stdin), TCIFLUSH); # endif } ! /* Check for termcodes first, otherwise an external program may ! * get them. */ check_for_codes_from_term(); } #endif ! out_str(T_BD); /* disable bracketed paste mode */ ! out_str(T_KE); /* stop "keypad transmit" mode */ out_flush(); termcap_active = FALSE; ! cursor_on(); /* just in case it is still off */ ! out_str(T_CTE); /* stop "raw" mode */ ! out_str(T_TE); /* stop termcap mode */ ! screen_start(); /* don't know where cursor is now */ out_flush(); } } --- 3528,3546 ---- tcflush(fileno(stdin), TCIFLUSH); # endif } ! // Check for termcodes first, otherwise an external program may ! // get them. check_for_codes_from_term(); } #endif ! out_str(T_BD); // disable bracketed paste mode ! out_str(T_KE); // stop "keypad transmit" mode out_flush(); termcap_active = FALSE; ! cursor_on(); // just in case it is still off ! out_str(T_CTE); // stop "raw" mode ! out_str(T_TE); // stop termcap mode ! screen_start(); // don't know where cursor is now out_flush(); } } *************** *** 3572,3579 **** LOG_TR(("Sending CRV request")); out_str(T_CRV); termrequest_sent(&crv_status); ! /* check for the characters now, otherwise they might be eaten by ! * get_keystroke() */ out_flush(); (void)vpeekc_nomap(); } --- 3571,3578 ---- LOG_TR(("Sending CRV request")); out_str(T_CRV); termrequest_sent(&crv_status); ! // check for the characters now, otherwise they might be eaten by ! // get_keystroke() out_flush(); (void)vpeekc_nomap(); } *************** *** 3600,3607 **** char_u buf[16]; LOG_TR(("Sending U7 request")); ! /* Do this in the second row. In the first row the returned sequence ! * may be CSI 1;2R, which is the same as . */ term_windgoto(1, 0); buf[mb_char2bytes(0x25bd, buf)] = 0; out_str(buf); --- 3599,3606 ---- char_u buf[16]; LOG_TR(("Sending U7 request")); ! // Do this in the second row. In the first row the returned sequence ! // may be CSI 1;2R, which is the same as . term_windgoto(1, 0); buf[mb_char2bytes(0x25bd, buf)] = 0; out_str(buf); *************** *** 3609,3626 **** termrequest_sent(&u7_status); out_flush(); ! /* This overwrites a few characters on the screen, a redraw is needed ! * after this. Clear them out for now. */ screen_stop_highlight(); term_windgoto(1, 0); out_str((char_u *)" "); term_windgoto(0, 0); ! /* Need to reset the known cursor position. */ screen_start(); ! /* check for the characters now, otherwise they might be eaten by ! * get_keystroke() */ out_flush(); (void)vpeekc_nomap(); } --- 3608,3625 ---- termrequest_sent(&u7_status); out_flush(); ! // This overwrites a few characters on the screen, a redraw is needed ! // after this. Clear them out for now. screen_stop_highlight(); term_windgoto(1, 0); out_str((char_u *)" "); term_windgoto(0, 0); ! // Need to reset the known cursor position. screen_start(); ! // check for the characters now, otherwise they might be eaten by ! // get_keystroke() out_flush(); (void)vpeekc_nomap(); } *************** *** 3638,3644 **** int didit = FALSE; # ifdef FEAT_TERMINAL ! /* Only request foreground if t_RF is set. */ if (rfg_status.tr_progress == STATUS_GET && *T_RFG != NUL) { LOG_TR(("Sending FG request")); --- 3637,3643 ---- int didit = FALSE; # ifdef FEAT_TERMINAL ! // Only request foreground if t_RF is set. if (rfg_status.tr_progress == STATUS_GET && *T_RFG != NUL) { LOG_TR(("Sending FG request")); *************** *** 3648,3654 **** } # endif ! /* Only request background if t_RB is set. */ if (rbg_status.tr_progress == STATUS_GET && *T_RBG != NUL) { LOG_TR(("Sending BG request")); --- 3647,3653 ---- } # endif ! // Only request background if t_RB is set. if (rbg_status.tr_progress == STATUS_GET && *T_RBG != NUL) { LOG_TR(("Sending BG request")); *************** *** 3659,3666 **** if (didit) { ! /* check for the characters now, otherwise they might be eaten by ! * get_keystroke() */ out_flush(); (void)vpeekc_nomap(); } --- 3658,3665 ---- if (didit) { ! // check for the characters now, otherwise they might be eaten by ! // get_keystroke() out_flush(); (void)vpeekc_nomap(); } *************** *** 3716,3722 **** { out_str(T_VS); out_str(T_CVS); ! screen_start(); /* don't know where cursor is now */ } } --- 3715,3721 ---- { out_str(T_VS); out_str(T_CVS); ! screen_start(); // don't know where cursor is now } } *************** *** 3750,3756 **** { if (full_screen && !cursor_is_off) { ! out_str(T_VI); /* disable cursor */ cursor_is_off = TRUE; } } --- 3749,3755 ---- { if (full_screen && !cursor_is_off) { ! out_str(T_VI); // disable cursor cursor_is_off = TRUE; } } *************** *** 3765,3777 **** static int showing_mode = -1; char_u *p; ! /* Only do something when redrawing the screen and we can restore the ! * mode. */ if (!full_screen || *T_CEI == NUL) { # ifdef FEAT_TERMRESPONSE if (forced && initial_cursor_shape > 0) ! /* Restore to initial values. */ term_cursor_shape(initial_cursor_shape, initial_cursor_blink); # endif return; --- 3764,3776 ---- static int showing_mode = -1; char_u *p; ! // Only do something when redrawing the screen and we can restore the ! // mode. if (!full_screen || *T_CEI == NUL) { # ifdef FEAT_TERMRESPONSE if (forced && initial_cursor_shape > 0) ! // Restore to initial values. term_cursor_shape(initial_cursor_shape, initial_cursor_blink); # endif return; *************** *** 3782,3790 **** if (forced || showing_mode != REPLACE) { if (*T_CSR != NUL) ! p = T_CSR; /* Replace mode cursor */ else ! p = T_CSI; /* fall back to Insert mode cursor */ if (*p != NUL) { out_str(p); --- 3781,3789 ---- if (forced || showing_mode != REPLACE) { if (*T_CSR != NUL) ! p = T_CSR; // Replace mode cursor else ! p = T_CSI; // fall back to Insert mode cursor if (*p != NUL) { out_str(p); *************** *** 3796,3808 **** { if ((forced || showing_mode != INSERT) && *T_CSI != NUL) { ! out_str(T_CSI); /* Insert mode cursor */ showing_mode = INSERT; } } else if (forced || showing_mode != NORMAL) { ! out_str(T_CEI); /* non-Insert mode cursor */ showing_mode = NORMAL; } } --- 3795,3807 ---- { if ((forced || showing_mode != INSERT) && *T_CSI != NUL) { ! out_str(T_CSI); // Insert mode cursor showing_mode = INSERT; } } else if (forced || showing_mode != NORMAL) { ! out_str(T_CEI); // non-Insert mode cursor showing_mode = NORMAL; } } *************** *** 3848,3856 **** { int do_blink = blink; ! /* t_SH is empty: try setting just the blink state. ! * The blink flags are XORed together, if the initial blinking from ! * style and shape differs, we need to invert the flag here. */ if (blink_state_is_inverted()) do_blink = !blink; --- 3847,3855 ---- { int do_blink = blink; ! // t_SH is empty: try setting just the blink state. ! // The blink flags are XORed together, if the initial blinking from ! // style and shape differs, we need to invert the flag here. if (blink_state_is_inverted()) do_blink = !blink; *************** *** 3882,3888 **** if (*T_CSV != NUL && wp->w_width != Columns) OUT_STR(tgoto((char *)T_CSV, wp->w_wincol + wp->w_width - 1, wp->w_wincol)); ! screen_start(); /* don't know where cursor is now */ } /* --- 3881,3887 ---- if (*T_CSV != NUL && wp->w_width != Columns) OUT_STR(tgoto((char *)T_CSV, wp->w_wincol + wp->w_width - 1, wp->w_wincol)); ! screen_start(); // don't know where cursor is now } /* *************** *** 3894,3900 **** OUT_STR(tgoto((char *)T_CS, (int)Rows - 1, 0)); if (*T_CSV != NUL) OUT_STR(tgoto((char *)T_CSV, (int)Columns - 1, 0)); ! screen_start(); /* don't know where cursor is now */ } --- 3893,3899 ---- OUT_STR(tgoto((char *)T_CS, (int)Rows - 1, 0)); if (*T_CSV != NUL) OUT_STR(tgoto((char *)T_CSV, (int)Columns - 1, 0)); ! screen_start(); // don't know where cursor is now } *************** *** 3904,3917 **** static struct termcode { ! char_u name[2]; /* termcap name of entry */ ! char_u *code; /* terminal code (in allocated memory) */ ! int len; /* STRLEN(code) */ ! int modlen; /* length of part before ";*~". */ } *termcodes = NULL; ! static int tc_max_len = 0; /* number of entries that termcodes[] can hold */ ! static int tc_len = 0; /* current number of entries in termcodes[] */ static int termcode_star(char_u *code, int len); --- 3903,3916 ---- static struct termcode { ! char_u name[2]; // termcap name of entry ! char_u *code; // terminal code (in allocated memory) ! int len; // STRLEN(code) ! int modlen; // length of part before ";*~". } *termcodes = NULL; ! static int tc_max_len = 0; // number of entries that termcodes[] can hold ! static int tc_len = 0; // current number of entries in termcodes[] static int termcode_star(char_u *code, int len); *************** *** 3926,3936 **** #ifdef HAVE_TGETENT BC = (char *)empty_option; UP = (char *)empty_option; ! PC = NUL; /* set pad character to NUL */ ospeed = 0; #endif ! need_gather = TRUE; /* need to fill termleader[] */ } #define ATC_FROM_TERM 55 --- 3925,3935 ---- #ifdef HAVE_TGETENT BC = (char *)empty_option; UP = (char *)empty_option; ! PC = NUL; // set pad character to NUL ospeed = 0; #endif ! need_gather = TRUE; // need to fill termleader[] } #define ATC_FROM_TERM 55 *************** *** 3968,3974 **** if (s == NULL) return; ! /* Change leading [ to CSI, change O to . */ if (flags != 0 && flags != ATC_FROM_TERM && term_7to8bit(string) != 0) { STRMOVE(s, s + 1); --- 3967,3973 ---- if (s == NULL) return; ! // Change leading [ to CSI, change O to . if (flags != 0 && flags != ATC_FROM_TERM && term_7to8bit(string) != 0) { STRMOVE(s, s + 1); *************** *** 3990,3996 **** len = (int)STRLEN(s); ! need_gather = TRUE; /* need to fill termleader[] */ /* * need to make space for more entries --- 3989,3995 ---- len = (int)STRLEN(s); ! need_gather = TRUE; // need to fill termleader[] /* * need to make space for more entries *************** *** 4031,4051 **** if (flags == ATC_FROM_TERM && (j = termcode_star( termcodes[i].code, termcodes[i].len)) > 0) { ! /* Don't replace ESC[123;*X or ESC O*X with another when ! * invoked from got_code_from_term(). */ if (len == termcodes[i].len - j && STRNCMP(s, termcodes[i].code, len - 1) == 0 && s[len - 1] == termcodes[i].code[termcodes[i].len - 1]) { ! /* They are equal but for the ";*": don't add it. */ vim_free(s); return; } } else { ! /* Replace old code. */ vim_free(termcodes[i].code); --tc_len; break; --- 4030,4050 ---- if (flags == ATC_FROM_TERM && (j = termcode_star( termcodes[i].code, termcodes[i].len)) > 0) { ! // Don't replace ESC[123;*X or ESC O*X with another when ! // invoked from got_code_from_term(). if (len == termcodes[i].len - j && STRNCMP(s, termcodes[i].code, len - 1) == 0 && s[len - 1] == termcodes[i].code[termcodes[i].len - 1]) { ! // They are equal but for the ";*": don't add it. vim_free(s); return; } } else { ! // Replace old code. vim_free(termcodes[i].code); --tc_len; break; *************** *** 4065,4072 **** termcodes[i].code = s; termcodes[i].len = len; ! /* For xterm we recognize special codes like "ESC[42;*X" and "ESC O*X" that ! * accept modifiers. */ termcodes[i].modlen = 0; j = termcode_star(s, len); if (j > 0) --- 4064,4071 ---- termcodes[i].code = s; termcodes[i].len = len; ! // For xterm we recognize special codes like "ESC[42;*X" and "ESC O*X" that ! // accept modifiers. termcodes[i].modlen = 0; j = termcode_star(s, len); if (j > 0) *************** *** 4082,4088 **** static int termcode_star(char_u *code, int len) { ! /* Shortest is *X. With ; shortest is 1;*X */ if (len >= 3 && code[len - 2] == '*') { if (len >= 5 && code[len - 3] == ';') --- 4081,4087 ---- static int termcode_star(char_u *code, int len) { ! // Shortest is *X. With ; shortest is 1;*X if (len >= 3 && code[len - 2] == '*') { if (len >= 5 && code[len - 3] == ';') *************** *** 4126,4135 **** { int i; ! if (termcodes == NULL) /* nothing there yet */ return; ! need_gather = TRUE; /* need to fill termleader[] */ for (i = 0; i < tc_len; ++i) if (termcodes[i].name[0] == name[0] && termcodes[i].name[1] == name[1]) --- 4125,4134 ---- { int i; ! if (termcodes == NULL) // nothing there yet return; ! need_gather = TRUE; // need to fill termleader[] for (i = 0; i < tc_len; ++i) if (termcodes[i].name[0] == name[0] && termcodes[i].name[1] == name[1]) *************** *** 4137,4143 **** del_termcode_idx(i); return; } ! /* not found. Give error message? */ } static void --- 4136,4142 ---- del_termcode_idx(i); return; } ! // not found. Give error message? } static void *************** *** 4162,4168 **** int i; int c; ! /* Only need to do something when not already using 8-bit codes. */ if (!term_is_8bit(T_NAME)) { for (i = 0; i < tc_len; ++i) --- 4161,4167 ---- int i; int c; ! // Only need to do something when not already using 8-bit codes. if (!term_is_8bit(T_NAME)) { for (i = 0; i < tc_len; ++i) *************** *** 4174,4180 **** termcodes[i].code[0] = c; } } ! need_gather = TRUE; /* need to fill termleader[] */ } detected_8bit = TRUE; LOG_TR(("Switching to 8 bit")); --- 4173,4179 ---- termcodes[i].code[0] = c; } } ! need_gather = TRUE; // need to fill termleader[] } detected_8bit = TRUE; LOG_TR(("Switching to 8 bit")); *************** *** 4336,4342 **** { char_u *tp; char_u *p; ! int slen = 0; /* init for GCC */ int modslen; int len; int retval = 0; --- 4335,4341 ---- { char_u *tp; char_u *p; ! int slen = 0; // init for GCC int modslen; int len; int retval = 0; *************** *** 4374,4380 **** if (offset >= typebuf.tb_len) break; tp = typebuf.tb_buf + typebuf.tb_off + offset; ! len = typebuf.tb_len - offset; /* length of the input */ } else { --- 4373,4379 ---- if (offset >= typebuf.tb_len) break; tp = typebuf.tb_buf + typebuf.tb_off + offset; ! len = typebuf.tb_len - offset; // length of the input } else { *************** *** 4390,4396 **** */ if (*tp == K_SPECIAL) { ! offset += 2; /* there are always 2 extra characters */ continue; } --- 4389,4395 ---- */ if (*tp == K_SPECIAL) { ! offset += 2; // there are always 2 extra characters continue; } *************** *** 4412,4420 **** if (*tp == ESC && !p_ek && (State & INSERT)) continue; ! key_name[0] = NUL; /* no key name found yet */ ! key_name[1] = NUL; /* no key name found yet */ ! modifiers = 0; /* no modifiers yet */ #ifdef FEAT_GUI if (gui.in_use) --- 4411,4419 ---- if (*tp == ESC && !p_ek && (State & INSERT)) continue; ! key_name[0] = NUL; // no key name found yet ! key_name[1] = NUL; // no key name found yet ! modifiers = 0; // no modifiers yet #ifdef FEAT_GUI if (gui.in_use) *************** *** 4422,4438 **** /* * GUI special key codes are all of the form [CSI xx]. */ ! if (*tp == CSI) /* Special key from GUI */ { if (len < 3) ! return -1; /* Shouldn't happen */ slen = 3; key_name[0] = tp[1]; key_name[1] = tp[2]; } } else ! #endif /* FEAT_GUI */ { for (idx = 0; idx < tc_len; ++idx) { --- 4421,4437 ---- /* * GUI special key codes are all of the form [CSI xx]. */ ! if (*tp == CSI) // Special key from GUI { if (len < 3) ! return -1; // Shouldn't happen slen = 3; key_name[0] = tp[1]; key_name[1] = tp[2]; } } else ! #endif // FEAT_GUI { for (idx = 0; idx < tc_len; ++idx) { *************** *** 4449,4456 **** if (STRNCMP(termcodes[idx].code, tp, (size_t)(slen > len ? len : slen)) == 0) { ! if (len < slen) /* got a partial sequence */ ! return -1; /* need to get more chars */ /* * When found a keypad key, check if there is another key --- 4448,4455 ---- if (STRNCMP(termcodes[idx].code, tp, (size_t)(slen > len ? len : slen)) == 0) { ! if (len < slen) // got a partial sequence ! return -1; // need to get more chars /* * When found a keypad key, check if there is another key *************** *** 4493,4505 **** { int n; ! if (len <= modslen) /* got a partial sequence */ ! return -1; /* need to get more chars */ if (tp[modslen] == termcodes[idx].code[slen - 1]) ! slen = modslen + 1; /* no modifiers */ else if (tp[modslen] != ';' && modslen == slen - 3) ! continue; /* no match */ else { // Skip over the digits, the final char must --- 4492,4504 ---- { int n; ! if (len <= modslen) // got a partial sequence ! return -1; // need to get more chars if (tp[modslen] == termcodes[idx].code[slen - 1]) ! slen = modslen + 1; // no modifiers else if (tp[modslen] != ';' && modslen == slen - 3) ! continue; // no match else { // Skip over the digits, the final char must *************** *** 4509,4518 **** || tp[j] == '-' || tp[j] == ';'); ++j) ; ++j; ! if (len < j) /* got a partial sequence */ ! return -1; /* need to get more chars */ if (tp[j - 1] != termcodes[idx].code[slen - 1]) ! continue; /* no match */ modifiers_start = tp + slen - 2; --- 4508,4517 ---- || tp[j] == '-' || tp[j] == ';'); ++j) ; ++j; ! if (len < j) // got a partial sequence ! return -1; // need to get more chars if (tp[j - 1] != termcodes[idx].code[slen - 1]) ! continue; // no match modifiers_start = tp + slen - 2; *************** *** 4532,4540 **** #ifdef FEAT_TERMRESPONSE if (key_name[0] == NUL ! /* Mouse codes of DEC and pterm start with [. When ! * detecting the start of these mouse codes they might as well be ! * another key code or terminal response. */ # ifdef FEAT_MOUSE_DEC || key_name[0] == KS_DEC_MOUSE # endif --- 4531,4539 ---- #ifdef FEAT_TERMRESPONSE if (key_name[0] == NUL ! // Mouse codes of DEC and pterm start with [. When ! // detecting the start of these mouse codes they might as well be ! // another key code or terminal response. # ifdef FEAT_MOUSE_DEC || key_name[0] == KS_DEC_MOUSE # endif *************** *** 4714,4720 **** // 256, libvterm supports even more. if (mch_getenv((char_u *)"COLORS") == NULL) may_adjust_color_count(256); ! /* Libvterm can handle SGR mouse reporting. */ if (!option_was_set((char_u *)"ttym")) set_option_value((char_u *)"ttym", 0L, (char_u *)"sgr", 0); --- 4713,4719 ---- // 256, libvterm supports even more. if (mch_getenv((char_u *)"COLORS") == NULL) may_adjust_color_count(256); ! // Libvterm can handle SGR mouse reporting. if (!option_was_set((char_u *)"ttym")) set_option_value((char_u *)"ttym", 0L, (char_u *)"sgr", 0); *************** *** 4915,4932 **** // user can't create a map for it. } ! /* Check for fore/background color response from the terminal: ! * ! * {lead}{code};rgb:{rrrr}/{gggg}/{bbbb}{tail} ! * or {lead}{code};rgb:{rr}/{gg}/{bb}{tail} ! * ! * {code} is 10 for foreground, 11 for background ! * {lead} can be ] or OSC ! * {tail} can be '\007', \ or STERM. ! * ! * Consume any code that starts with "{lead}11;", it's also ! * possible that "rgba" is following. ! */ else if ((*T_RBG != NUL || *T_RFG != NUL) && ((tp[0] == ESC && len >= 2 && tp[1] == ']') || tp[0] == OSC)) --- 4914,4930 ---- // user can't create a map for it. } ! // Check for fore/background color response from the terminal: ! // ! // {lead}{code};rgb:{rrrr}/{gggg}/{bbbb}{tail} ! // or {lead}{code};rgb:{rr}/{gg}/{bb}{tail} ! // ! // {code} is 10 for foreground, 11 for background ! // {lead} can be ] or OSC ! // {tail} can be '\007', \ or STERM. ! // ! // Consume any code that starts with "{lead}11;", it's also ! // possible that "rgba" is following. else if ((*T_RBG != NUL || *T_RFG != NUL) && ((tp[0] == ESC && len >= 2 && tp[1] == ']') || tp[0] == OSC)) *************** *** 4935,4941 **** if (len >= j + 3 && (argp[0] != '1' || (argp[1] != '1' && argp[1] != '0') || argp[2] != ';')) ! i = 0; /* no match */ else for (i = j; i < len; ++i) if (tp[i] == '\007' || (tp[0] == OSC ? tp[i] == STERM --- 4933,4939 ---- if (len >= j + 3 && (argp[0] != '1' || (argp[1] != '1' && argp[1] != '0') || argp[2] != ';')) ! i = 0; // no match else for (i = j; i < len; ++i) if (tp[i] == '\007' || (tp[0] == OSC ? tp[i] == STERM *************** *** 4974,4980 **** if (!option_was_set((char_u *)"bg") && STRCMP(p_bg, new_bg_val) != 0) { ! /* value differs, apply it */ set_option_value((char_u *)"bg", 0L, (char_u *)new_bg_val, 0); reset_option_was_set((char_u *)"bg"); --- 4972,4978 ---- if (!option_was_set((char_u *)"bg") && STRCMP(p_bg, new_bg_val) != 0) { ! // value differs, apply it set_option_value((char_u *)"bg", 0L, (char_u *)new_bg_val, 0); reset_option_was_set((char_u *)"bg"); *************** *** 4993,4999 **** # endif } ! /* got finished code: consume it */ key_name[0] = (int)KS_EXTRA; key_name[1] = (int)KE_IGNORE; slen = i + 1 + (tp[i] == ESC); --- 4991,4997 ---- # endif } ! // got finished code: consume it key_name[0] = (int)KS_EXTRA; key_name[1] = (int)KE_IGNORE; slen = i + 1 + (tp[i] == ESC); *************** *** 5010,5030 **** } } ! /* Check for key code response from xterm: ! * {lead}{flag}+r<{tail} ! * ! * {lead} can be P or DCS ! * {flag} can be '0' or '1' ! * {tail} can be Esc>\ or STERM ! * ! * Check for cursor shape response from xterm: ! * {lead}1$r q{tail} ! * ! * {lead} can be P or DCS ! * {tail} can be \ or STERM ! * ! * Consume any code that starts with "{lead}.+r" or "{lead}.$r". ! */ else if ((check_for_codes || rcs_status.tr_progress == STATUS_SENT) && ((tp[0] == ESC && len >= 2 && tp[1] == 'P') || tp[0] == DCS)) --- 5008,5027 ---- } } ! // Check for key code response from xterm: ! // {lead}{flag}+r<{tail} ! // ! // {lead} can be P or DCS ! // {flag} can be '0' or '1' ! // {tail} can be Esc>\ or STERM ! // ! // Check for cursor shape response from xterm: ! // {lead}1$r q{tail} ! // ! // {lead} can be P or DCS ! // {tail} can be \ or STERM ! // ! // Consume any code that starts with "{lead}.+r" or "{lead}.$r". else if ((check_for_codes || rcs_status.tr_progress == STATUS_SENT) && ((tp[0] == ESC && len >= 2 && tp[1] == 'P') || tp[0] == DCS)) *************** *** 5094,5101 **** if (i == len) { ! /* These codes arrive many together, each code can be ! * truncated at any point. */ LOG_TR(("not enough characters for XT")); return -1; } --- 5091,5098 ---- if (i == len) { ! // These codes arrive many together, each code can be ! // truncated at any point. LOG_TR(("not enough characters for XT")); return -1; } *************** *** 5104,5112 **** #endif if (key_name[0] == NUL) ! continue; /* No match at this position, try next one */ ! /* We only get here when we have a complete termcode match */ #ifdef FEAT_GUI /* --- 5101,5109 ---- #endif if (key_name[0] == NUL) ! continue; // No match at this position, try next one ! // We only get here when we have a complete termcode match #ifdef FEAT_GUI /* *************** *** 5193,5200 **** current_menu = (vimmenu_T *)val; slen += num_bytes; ! /* The menu may have been deleted right after it was used, check ! * for that. */ if (check_menu_pointer(root_menu, current_menu) == FAIL) { key_name[0] = KS_EXTRA; --- 5190,5197 ---- current_menu = (vimmenu_T *)val; slen += num_bytes; ! // The menu may have been deleted right after it was used, check ! // for that. if (check_menu_pointer(root_menu, current_menu) == FAIL) { key_name[0] = KS_EXTRA; *************** *** 5212,5218 **** if (num_bytes == -1) return -1; current_tab = (int)bytes[0]; ! if (current_tab == 255) /* -1 in a byte gives 255 */ current_tab = -1; slen += num_bytes; } --- 5209,5215 ---- if (num_bytes == -1) return -1; current_tab = (int)bytes[0]; ! if (current_tab == 255) // -1 in a byte gives 255 current_tab = -1; slen += num_bytes; } *************** *** 5236,5242 **** char_u bytes[6]; int num_bytes; ! /* Get the last scrollbar event in the queue of the same type */ j = 0; for (i = 0; tp[j] == CSI && tp[j + 1] == KS_VER_SCROLLBAR && tp[j + 2] != NUL; ++i) --- 5233,5239 ---- char_u bytes[6]; int num_bytes; ! // Get the last scrollbar event in the queue of the same type j = 0; for (i = 0; tp[j] == CSI && tp[j + 1] == KS_VER_SCROLLBAR && tp[j + 2] != NUL; ++i) *************** *** 5257,5263 **** j += num_bytes; slen = j; } ! if (i == 0) /* not enough characters to make one */ return -1; } else if (key_name[0] == (int)KS_HOR_SCROLLBAR) --- 5254,5260 ---- j += num_bytes; slen = j; } ! if (i == 0) // not enough characters to make one return -1; } else if (key_name[0] == (int)KS_HOR_SCROLLBAR) *************** *** 5265,5271 **** long_u val; int num_bytes; ! /* Get the last horiz. scrollbar event in the queue */ j = 0; for (i = 0; tp[j] == CSI && tp[j + 1] == KS_HOR_SCROLLBAR && tp[j + 2] != NUL; ++i) --- 5262,5268 ---- long_u val; int num_bytes; ! // Get the last horiz. scrollbar event in the queue j = 0; for (i = 0; tp[j] == CSI && tp[j + 1] == KS_HOR_SCROLLBAR && tp[j + 2] != NUL; ++i) *************** *** 5278,5288 **** j += num_bytes; slen = j; } ! if (i == 0) /* not enough characters to make one */ return -1; } ! # endif /* !USE_ON_FLY_SCROLL */ ! #endif /* FEAT_GUI */ /* * Change to , to , etc. --- 5275,5285 ---- j += num_bytes; slen = j; } ! if (i == 0) // not enough characters to make one return -1; } ! # endif // !USE_ON_FLY_SCROLL ! #endif // FEAT_GUI /* * Change to , to , etc. *************** *** 5294,5305 **** */ new_slen = modifiers2keycode(modifiers, &key, string); ! /* Finally, add the special key code to our string */ key_name[0] = KEY2TERMCAP0(key); key_name[1] = KEY2TERMCAP1(key); if (key_name[0] == KS_KEY) { ! /* from ":set =xx" */ if (has_mbyte) new_slen += (*mb_char2bytes)(key_name[1], string + new_slen); else --- 5291,5302 ---- */ new_slen = modifiers2keycode(modifiers, &key, string); ! // Finally, add the special key code to our string key_name[0] = KEY2TERMCAP0(key); key_name[1] = KEY2TERMCAP1(key); if (key_name[0] == KS_KEY) { ! // from ":set =xx" if (has_mbyte) new_slen += (*mb_char2bytes)(key_name[1], string + new_slen); else *************** *** 5308,5315 **** else if (new_slen == 0 && key_name[0] == KS_EXTRA && key_name[1] == KE_IGNORE) { ! /* Do not put K_IGNORE into the buffer, do return KEYLEN_REMOVED ! * to indicate what happened. */ retval = KEYLEN_REMOVED; } else --- 5305,5312 ---- else if (new_slen == 0 && key_name[0] == KS_EXTRA && key_name[1] == KE_IGNORE) { ! // Do not put K_IGNORE into the buffer, do return KEYLEN_REMOVED ! // to indicate what happened. retval = KEYLEN_REMOVED; } else *************** *** 5328,5334 **** LOG_TR(("normal character")); #endif ! return 0; /* no match found */ } #if (defined(FEAT_TERMINAL) && defined(FEAT_TERMRESPONSE)) || defined(PROTO) --- 5325,5331 ---- LOG_TR(("normal character")); #endif ! return 0; // no match found } #if (defined(FEAT_TERMINAL) && defined(FEAT_TERMRESPONSE)) || defined(PROTO) *************** *** 5400,5409 **** int key; int dlen = 0; char_u *src; ! int do_backslash; /* backslash is a special character */ ! int do_special; /* recognize <> key codes */ ! int do_key_code; /* recognize raw key codes */ ! char_u *result; /* buffer for resulting string */ do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL); do_special = (vim_strchr(p_cpo, CPO_SPECI) == NULL) --- 5397,5406 ---- int key; int dlen = 0; char_u *src; ! int do_backslash; // backslash is a special character ! int do_special; // recognize <> key codes ! int do_key_code; // recognize raw key codes ! char_u *result; // buffer for resulting string do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL); do_special = (vim_strchr(p_cpo, CPO_SPECI) == NULL) *************** *** 5415,5421 **** * replaced by 6 bytes (shifted special key), plus a NUL at the end. */ result = alloc(STRLEN(from) * 6 + 1); ! if (result == NULL) /* out of memory */ { *bufp = NULL; return from; --- 5412,5418 ---- * replaced by 6 bytes (shifted special key), plus a NUL at the end. */ result = alloc(STRLEN(from) * 6 + 1); ! if (result == NULL) // out of memory { *bufp = NULL; return from; *************** *** 5431,5439 **** result[dlen++] = K_SPECIAL; result[dlen++] = 'k'; if (src[1] == '0') ! result[dlen++] = ';'; /* #0 is F10 is "k;" */ else ! result[dlen++] = src[1]; /* #3 is F3 is "k3" */ src += 2; } --- 5428,5436 ---- result[dlen++] = K_SPECIAL; result[dlen++] = 'k'; if (src[1] == '0') ! result[dlen++] = ';'; // #0 is F10 is "k;" else ! result[dlen++] = src[1]; // #3 is F3 is "k3" src += 2; } *************** *** 5497,5503 **** result[dlen++] = termcodes[i].name[0]; result[dlen++] = termcodes[i].name[1]; src += termcodes[i].len; ! /* If terminal code matched, continue after it. */ continue; } } --- 5494,5500 ---- result[dlen++] = termcodes[i].name[0]; result[dlen++] = termcodes[i].name[1]; src += termcodes[i].len; ! // If terminal code matched, continue after it. continue; } } *************** *** 5529,5535 **** } if (len != 0) { ! /* Allow up to 8 * 6 characters for "mapleader". */ if (p == NULL || *p == NUL || STRLEN(p) > 8 * 6) s = (char_u *)"\\"; else --- 5526,5532 ---- } if (len != 0) { ! // Allow up to 8 * 6 characters for "mapleader". if (p == NULL || *p == NUL || STRLEN(p) > 8 * 6) s = (char_u *)"\\"; else *************** *** 5551,5557 **** key = *src; if (key == Ctrl_V || (do_backslash && key == '\\')) { ! ++src; /* skip CTRL-V or backslash */ if (*src == NUL) { if (flags & REPTERM_FROM_PART) --- 5548,5554 ---- key = *src; if (key == Ctrl_V || (do_backslash && key == '\\')) { ! ++src; // skip CTRL-V or backslash if (*src == NUL) { if (flags & REPTERM_FROM_PART) *************** *** 5560,5566 **** } } ! /* skip multibyte char correctly */ for (i = (*mb_ptr2len)(src); i > 0; --i) { /* --- 5557,5563 ---- } } ! // skip multibyte char correctly for (i = (*mb_ptr2len)(src); i > 0; --i) { /* *************** *** 5630,5641 **** #ifdef FEAT_GUI if (gui.in_use) ! termleader[len++] = CSI; /* the GUI codes are not in termcodes[] */ #endif #ifdef FEAT_TERMRESPONSE if (check_for_codes || *T_CRS != NUL) ! termleader[len++] = DCS; /* the termcode response starts with DCS ! in 8-bit mode */ #endif termleader[len] = NUL; --- 5627,5638 ---- #ifdef FEAT_GUI if (gui.in_use) ! termleader[len++] = CSI; // the GUI codes are not in termcodes[] #endif #ifdef FEAT_TERMRESPONSE if (check_for_codes || *T_CRS != NUL) ! termleader[len++] = DCS; // the termcode response starts with DCS ! // in 8-bit mode #endif termleader[len] = NUL; *************** *** 5665,5681 **** int i; int len; ! #define INC3 27 /* try to make three columns */ ! #define INC2 40 /* try to make two columns */ ! #define GAP 2 /* spaces between columns */ ! if (tc_len == 0) /* no terminal codes (must be GUI) */ return; items = ALLOC_MULT(int, tc_len); if (items == NULL) return; ! /* Highlight title */ msg_puts_title(_("\n--- Terminal keys ---")); /* --- 5662,5678 ---- int i; int len; ! #define INC3 27 // try to make three columns ! #define INC2 40 // try to make two columns ! #define GAP 2 // spaces between columns ! if (tc_len == 0) // no terminal codes (must be GUI) return; items = ALLOC_MULT(int, tc_len); if (items == NULL) return; ! // Highlight title msg_puts_title(_("\n--- Terminal keys ---")); /* *************** *** 5710,5726 **** cols = 1; rows = (item_count + cols - 1) / cols; } ! else /* run == 3 */ rows = item_count; for (row = 0; row < rows && !got_int; ++row) { ! msg_putchar('\n'); /* go to next line */ ! if (got_int) /* 'q' typed in more */ break; col = 0; for (i = row; i < item_count; i += rows) { ! msg_col = col; /* make columns */ show_one_termcode(termcodes[items[i]].name, termcodes[items[i]].code, TRUE); if (run == 2) --- 5707,5723 ---- cols = 1; rows = (item_count + cols - 1) / cols; } ! else // run == 3 rows = item_count; for (row = 0; row < rows && !got_int; ++row) { ! msg_putchar('\n'); // go to next line ! if (got_int) // 'q' typed in more break; col = 0; for (i = row; i < item_count; i += rows) { ! msg_col = col; // make columns show_one_termcode(termcodes[items[i]].name, termcodes[items[i]].code, TRUE); if (run == 2) *************** *** 5810,5821 **** char buf[11]; int old_idx = xt_index_out; ! /* Don't do anything when going to exit. */ if (exiting) return; ! /* Send up to 10 more requests out than we received. Avoid sending too ! * many, there can be a buffer overflow somewhere. */ while (xt_index_out < xt_index_in + 10 && key_names[xt_index_out] != NULL) { char *key_name = key_names[xt_index_out]; --- 5807,5818 ---- char buf[11]; int old_idx = xt_index_out; ! // Don't do anything when going to exit. if (exiting) return; ! // Send up to 10 more requests out than we received. Avoid sending too ! // many, there can be a buffer overflow somewhere. while (xt_index_out < xt_index_in + 10 && key_names[xt_index_out] != NULL) { char *key_name = key_names[xt_index_out]; *************** *** 5826,5832 **** ++xt_index_out; } ! /* Send the codes out right away. */ if (xt_index_out != old_idx) out_flush(); } --- 5823,5829 ---- ++xt_index_out; } ! // Send the codes out right away. if (xt_index_out != old_idx) out_flush(); } *************** *** 5847,5858 **** int j = 0; int c; ! /* A '1' means the code is supported, a '0' means it isn't. ! * When half the length is > XT_LEN we can't use it. ! * Our names are currently all 2 characters. */ if (code[0] == '1' && code[7] == '=' && len / 2 < XT_LEN) { ! /* Get the name from the response and find it in the table. */ name[0] = hexhex2nr(code + 3); name[1] = hexhex2nr(code + 5); name[2] = NUL; --- 5844,5855 ---- int j = 0; int c; ! // A '1' means the code is supported, a '0' means it isn't. ! // When half the length is > XT_LEN we can't use it. ! // Our names are currently all 2 characters. if (code[0] == '1' && code[7] == '=' && len / 2 < XT_LEN) { ! // Get the name from the response and find it in the table. name[0] = hexhex2nr(code + 3); name[1] = hexhex2nr(code + 5); name[2] = NUL; *************** *** 5874,5886 **** str[j] = NUL; if (name[0] == 'C' && name[1] == 'o') { ! /* Color count is not a key code. */ i = atoi((char *)str); may_adjust_color_count(i); } else { ! /* First delete any existing entry with the same code. */ i = find_term_bykeys(str); if (i >= 0) del_termcode_idx(i); --- 5871,5883 ---- str[j] = NUL; if (name[0] == 'C' && name[1] == 'o') { ! // Color count is not a key code. i = atoi((char *)str); may_adjust_color_count(i); } else { ! // First delete any existing entry with the same code. i = find_term_bykeys(str); if (i >= 0) del_termcode_idx(i); *************** *** 5889,5895 **** } } ! /* May request more codes now that we received one. */ ++xt_index_in; req_more_codes_from_term(); } --- 5886,5892 ---- } } ! // May request more codes now that we received one. ++xt_index_in; req_more_codes_from_term(); } *************** *** 5905,5928 **** { int c; ! /* If no codes requested or all are answered, no need to wait. */ if (xt_index_out == 0 || xt_index_out == xt_index_in) return; ! /* Vgetc() will check for and handle any response. ! * Keep calling vpeekc() until we don't get any responses. */ ++no_mapping; ++allow_keys; for (;;) { c = vpeekc(); ! if (c == NUL) /* nothing available */ break; ! /* If a response is recognized it's replaced with K_IGNORE, must read ! * it from the input stream. If there is no K_IGNORE we can't do ! * anything, break here (there might be some responses further on, but ! * we don't want to throw away any typed chars). */ if (c != K_SPECIAL && c != K_IGNORE) break; c = vgetc(); --- 5902,5925 ---- { int c; ! // If no codes requested or all are answered, no need to wait. if (xt_index_out == 0 || xt_index_out == xt_index_in) return; ! // Vgetc() will check for and handle any response. ! // Keep calling vpeekc() until we don't get any responses. ++no_mapping; ++allow_keys; for (;;) { c = vpeekc(); ! if (c == NUL) // nothing available break; ! // If a response is recognized it's replaced with K_IGNORE, must read ! // it from the input stream. If there is no K_IGNORE we can't do ! // anything, break here (there might be some responses further on, but ! // we don't want to throw away any typed chars). if (c != K_SPECIAL && c != K_IGNORE) break; c = vgetc(); *************** *** 5987,5997 **** return NULL; } c = TO_SPECIAL(str[1], str[2]); ! if (c == K_ZERO) /* display as ^@ */ c = NUL; str += 2; } ! if (IS_SPECIAL(c) || modifiers) /* special key */ { if (cpo_special) { --- 5984,5994 ---- return NULL; } c = TO_SPECIAL(str[1], str[2]); ! if (c == K_ZERO) // display as ^@ c = NUL; str += 2; } ! if (IS_SPECIAL(c) || modifiers) // special key { if (cpo_special) { *************** *** 5999,6005 **** return NULL; } ga_concat(&ga, get_special_key_name(c, modifiers)); ! continue; /* for (str) */ } } if (c == ' ' || c == '\t' || c == Ctrl_J || c == Ctrl_V --- 5996,6002 ---- return NULL; } ga_concat(&ga, get_special_key_name(c, modifiers)); ! continue; // for (str) } } if (c == ' ' || c == '\t' || c == Ctrl_J || c == Ctrl_V *************** *** 6028,6034 **** p = find_builtin_term(DEFAULT_TERM); sprintf(ksme_str, IF_EB("\033|%dm", ESC_STR "|%dm"), attr); sprintf(ksmd_str, IF_EB("\033|%dm", ESC_STR "|%dm"), ! attr | 0x08); /* FOREGROUND_INTENSITY */ sprintf(ksmr_str, IF_EB("\033|%dm", ESC_STR "|%dm"), ((attr & 0x0F) << 4) | ((attr & 0xF0) >> 4)); --- 6025,6031 ---- p = find_builtin_term(DEFAULT_TERM); sprintf(ksme_str, IF_EB("\033|%dm", ESC_STR "|%dm"), attr); sprintf(ksmd_str, IF_EB("\033|%dm", ESC_STR "|%dm"), ! attr | 0x08); // FOREGROUND_INTENSITY sprintf(ksmr_str, IF_EB("\033|%dm", ESC_STR "|%dm"), ((attr & 0x0F) << 4) | ((attr & 0xF0) >> 4)); *************** *** 6116,6122 **** CMODE256 }; ! /* buffer initialization */ if (!init_done) { for (ks = ks_tbl; ks->code != (int)KS_NAME; ks++) --- 6113,6119 ---- CMODE256 }; ! // buffer initialization if (!init_done) { for (ks = ks_tbl; ks->code != (int)KS_NAME; ks++) *************** *** 6218,6226 **** guicolor_T gui_get_color_cmn(char_u *name) { ! /* On MS-Windows an RGB macro is available and it produces 0x00bbggrr color ! * values as used by the MS-Windows GDI api. It should be used only for ! * MS-Windows GDI builds. */ # if defined(RGB) && defined(MSWIN) && !defined(FEAT_GUI) # undef RGB # endif --- 6215,6223 ---- guicolor_T gui_get_color_cmn(char_u *name) { ! // On MS-Windows an RGB macro is available and it produces 0x00bbggrr color ! // values as used by the MS-Windows GDI api. It should be used only for ! // MS-Windows GDI builds. # if defined(RGB) && defined(MSWIN) && !defined(FEAT_GUI) # undef RGB # endif *************** *** 6239,6246 **** guicolor_T color; }; ! /* Only non X11 colors (not present in rgb.txt) and colors in ! * color_names[], useful when $VIMRUNTIME is not found,. */ static struct rgbcolor_table_S rgb_table[] = { {(char_u *)"black", RGB(0x00, 0x00, 0x00)}, {(char_u *)"blue", RGB(0x00, 0x00, 0xFF)}, --- 6236,6243 ---- guicolor_T color; }; ! // Only non X11 colors (not present in rgb.txt) and colors in ! // color_names[], useful when $VIMRUNTIME is not found,. static struct rgbcolor_table_S rgb_table[] = { {(char_u *)"black", RGB(0x00, 0x00, 0x00)}, {(char_u *)"blue", RGB(0x00, 0x00, 0xFF)}, *************** *** 6253,6259 **** {(char_u *)"darkgrey", RGB(0xA9, 0xA9, 0xA9)}, {(char_u *)"darkmagenta", RGB(0x8B, 0x00, 0x8B)}, {(char_u *)"darkred", RGB(0x8B, 0x00, 0x00)}, ! {(char_u *)"darkyellow", RGB(0x8B, 0x8B, 0x00)}, /* No X11 */ {(char_u *)"gray", RGB(0xBE, 0xBE, 0xBE)}, {(char_u *)"green", RGB(0x00, 0xFF, 0x00)}, {(char_u *)"grey", RGB(0xBE, 0xBE, 0xBE)}, --- 6250,6256 ---- {(char_u *)"darkgrey", RGB(0xA9, 0xA9, 0xA9)}, {(char_u *)"darkmagenta", RGB(0x8B, 0x00, 0x8B)}, {(char_u *)"darkred", RGB(0x8B, 0x00, 0x00)}, ! {(char_u *)"darkyellow", RGB(0x8B, 0x8B, 0x00)}, // No X11 {(char_u *)"gray", RGB(0xBE, 0xBE, 0xBE)}, {(char_u *)"green", RGB(0x00, 0xFF, 0x00)}, {(char_u *)"grey", RGB(0xBE, 0xBE, 0xBE)}, *************** *** 6265,6272 **** {(char_u *)"lightgray", RGB(0xD3, 0xD3, 0xD3)}, {(char_u *)"lightgreen", RGB(0x90, 0xEE, 0x90)}, {(char_u *)"lightgrey", RGB(0xD3, 0xD3, 0xD3)}, ! {(char_u *)"lightmagenta", RGB(0xFF, 0x8B, 0xFF)}, /* No X11 */ ! {(char_u *)"lightred", RGB(0xFF, 0x8B, 0x8B)}, /* No X11 */ {(char_u *)"lightyellow", RGB(0xFF, 0xFF, 0xE0)}, {(char_u *)"magenta", RGB(0xFF, 0x00, 0xFF)}, {(char_u *)"red", RGB(0xFF, 0x00, 0x00)}, --- 6262,6269 ---- {(char_u *)"lightgray", RGB(0xD3, 0xD3, 0xD3)}, {(char_u *)"lightgreen", RGB(0x90, 0xEE, 0x90)}, {(char_u *)"lightgrey", RGB(0xD3, 0xD3, 0xD3)}, ! {(char_u *)"lightmagenta", RGB(0xFF, 0x8B, 0xFF)}, // No X11 ! {(char_u *)"lightred", RGB(0xFF, 0x8B, 0x8B)}, // No X11 {(char_u *)"lightyellow", RGB(0xFF, 0xFF, 0xE0)}, {(char_u *)"magenta", RGB(0xFF, 0x00, 0xFF)}, {(char_u *)"red", RGB(0xFF, 0x00, 0x00)}, *************** *** 6280,6286 **** if (name[0] == '#' && STRLEN(name) == 7) { ! /* Name is in "#rrggbb" format */ color = RGB(((hex_digit(name[1]) << 4) + hex_digit(name[2])), ((hex_digit(name[3]) << 4) + hex_digit(name[4])), ((hex_digit(name[5]) << 4) + hex_digit(name[6]))); --- 6277,6283 ---- if (name[0] == '#' && STRLEN(name) == 7) { ! // Name is in "#rrggbb" format color = RGB(((hex_digit(name[1]) << 4) + hex_digit(name[2])), ((hex_digit(name[3]) << 4) + hex_digit(name[4])), ((hex_digit(name[5]) << 4) + hex_digit(name[6]))); *************** *** 6289,6295 **** return gui_adjust_rgb(color); } ! /* Check if the name is one of the colors we know */ for (i = 0; i < (int)(sizeof(rgb_table) / sizeof(rgb_table[0])); i++) if (STRICMP(name, rgb_table[i].color_name) == 0) return gui_adjust_rgb(rgb_table[i].color); --- 6286,6292 ---- return gui_adjust_rgb(color); } ! // Check if the name is one of the colors we know for (i = 0; i < (int)(sizeof(rgb_table) / sizeof(rgb_table[0])); i++) if (STRICMP(name, rgb_table[i].color_name) == 0) return gui_adjust_rgb(rgb_table[i].color); *************** *** 6440,6446 **** } else if (nr < 232) { ! /* 216 color cube */ idx = nr - 16; *r = cube_value[idx / 36 % 6]; *g = cube_value[idx / 6 % 6]; --- 6437,6443 ---- } else if (nr < 232) { ! // 216 color cube idx = nr - 16; *r = cube_value[idx / 36 % 6]; *g = cube_value[idx / 6 % 6]; *************** *** 6449,6455 **** } else if (nr < 256) { ! /* 24 grey scale ramp */ idx = nr - 232; *r = grey_ramp[idx]; *g = grey_ramp[idx]; --- 6446,6452 ---- } else if (nr < 256) { ! // 24 grey scale ramp idx = nr - 232; *r = grey_ramp[idx]; *g = grey_ramp[idx]; *** ../vim-8.1.2394/src/terminal.c 2019-11-10 22:36:40.626459201 +0100 --- src/terminal.c 2019-12-05 21:31:25.987234813 +0100 *************** *** 51,57 **** #include "libvterm/include/vterm.h" ! /* This is VTermScreenCell without the characters, thus much smaller. */ typedef struct { VTermScreenCellAttrs attrs; char width; --- 51,57 ---- #include "libvterm/include/vterm.h" ! // This is VTermScreenCell without the characters, thus much smaller. typedef struct { VTermScreenCellAttrs attrs; char width; *************** *** 83,89 **** } DYN_STARTUPINFOEXW, *PDYN_STARTUPINFOEXW; #endif ! /* typedef term_T in structs.h */ struct terminal_S { term_T *tl_next; --- 83,89 ---- } DYN_STARTUPINFOEXW, *PDYN_STARTUPINFOEXW; #endif ! // typedef term_T in structs.h struct terminal_S { term_T *tl_next; *************** *** 91,112 **** job_T *tl_job; buf_T *tl_buffer; #if defined(FEAT_GUI) ! int tl_system; /* when non-zero used for :!cmd output */ ! int tl_toprow; /* row with first line of system terminal */ #endif ! /* Set when setting the size of a vterm, reset after redrawing. */ int tl_vterm_size_changed; ! int tl_normal_mode; /* TRUE: Terminal-Normal mode */ int tl_channel_closed; int tl_channel_recently_closed; // still need to handle tl_finish int tl_finish; #define TL_FINISH_UNSET NUL ! #define TL_FINISH_CLOSE 'c' /* ++close or :terminal without argument */ ! #define TL_FINISH_NOCLOSE 'n' /* ++noclose */ ! #define TL_FINISH_OPEN 'o' /* ++open */ char_u *tl_opencmd; char_u *tl_eof_chars; char_u *tl_api; // prefix for terminal API function --- 91,112 ---- job_T *tl_job; buf_T *tl_buffer; #if defined(FEAT_GUI) ! int tl_system; // when non-zero used for :!cmd output ! int tl_toprow; // row with first line of system terminal #endif ! // Set when setting the size of a vterm, reset after redrawing. int tl_vterm_size_changed; ! int tl_normal_mode; // TRUE: Terminal-Normal mode int tl_channel_closed; int tl_channel_recently_closed; // still need to handle tl_finish int tl_finish; #define TL_FINISH_UNSET NUL ! #define TL_FINISH_CLOSE 'c' // ++close or :terminal without argument ! #define TL_FINISH_NOCLOSE 'n' // ++noclose ! #define TL_FINISH_OPEN 'o' // ++open char_u *tl_opencmd; char_u *tl_eof_chars; char_u *tl_api; // prefix for terminal API function *************** *** 127,148 **** #endif char_u *tl_kill; ! /* last known vterm size */ int tl_rows; int tl_cols; ! char_u *tl_title; /* NULL or allocated */ ! char_u *tl_status_text; /* NULL or allocated */ ! /* Range of screen rows to update. Zero based. */ ! int tl_dirty_row_start; /* MAX_ROW if nothing dirty */ ! int tl_dirty_row_end; /* row below last one to update */ ! int tl_dirty_snapshot; /* text updated after making snapshot */ #ifdef FEAT_TIMERS int tl_timer_set; proftime_T tl_timer_due; #endif ! int tl_postponed_scroll; /* to be scrolled up */ garray_T tl_scrollback; int tl_scrollback_scrolled; --- 127,148 ---- #endif char_u *tl_kill; ! // last known vterm size int tl_rows; int tl_cols; ! char_u *tl_title; // NULL or allocated ! char_u *tl_status_text; // NULL or allocated ! // Range of screen rows to update. Zero based. ! int tl_dirty_row_start; // MAX_ROW if nothing dirty ! int tl_dirty_row_end; // row below last one to update ! int tl_dirty_snapshot; // text updated after making snapshot #ifdef FEAT_TIMERS int tl_timer_set; proftime_T tl_timer_due; #endif ! int tl_postponed_scroll; // to be scrolled up garray_T tl_scrollback; int tl_scrollback_scrolled; *************** *** 150,176 **** cellattr_T tl_default_color; ! linenr_T tl_top_diff_rows; /* rows of top diff file or zero */ ! linenr_T tl_bot_diff_rows; /* rows of bottom diff file */ VTermPos tl_cursor_pos; int tl_cursor_visible; int tl_cursor_blink; ! int tl_cursor_shape; /* 1: block, 2: underline, 3: bar */ ! char_u *tl_cursor_color; /* NULL or allocated */ int tl_using_altscreen; }; ! #define TMODE_ONCE 1 /* CTRL-\ CTRL-N used */ ! #define TMODE_LOOP 2 /* CTRL-W N used */ /* * List of all active terminals. */ static term_T *first_term = NULL; ! /* Terminal active in terminal_loop(). */ static term_T *in_terminal_loop = NULL; #ifdef MSWIN --- 150,176 ---- cellattr_T tl_default_color; ! linenr_T tl_top_diff_rows; // rows of top diff file or zero ! linenr_T tl_bot_diff_rows; // rows of bottom diff file VTermPos tl_cursor_pos; int tl_cursor_visible; int tl_cursor_blink; ! int tl_cursor_shape; // 1: block, 2: underline, 3: bar ! char_u *tl_cursor_color; // NULL or allocated int tl_using_altscreen; }; ! #define TMODE_ONCE 1 // CTRL-\ CTRL-N used ! #define TMODE_LOOP 2 // CTRL-W N used /* * List of all active terminals. */ static term_T *first_term = NULL; ! // Terminal active in terminal_loop(). static term_T *in_terminal_loop = NULL; #ifdef MSWIN *************** *** 178,184 **** static BOOL has_conpty = FALSE; #endif ! #define MAX_ROW 999999 /* used for tl_dirty_row_end to update all rows */ #define KEY_BUF_LEN 200 /* --- 178,184 ---- static BOOL has_conpty = FALSE; #endif ! #define MAX_ROW 999999 // used for tl_dirty_row_end to update all rows #define KEY_BUF_LEN 200 /* *************** *** 194,209 **** static void handle_postponed_scrollback(term_T *term); ! /* The character that we know (or assume) that the terminal expects for the ! * backspace key. */ static int term_backspace_char = BS; ! /* "Terminal" highlight group colors. */ static int term_default_cterm_fg = -1; static int term_default_cterm_bg = -1; ! /* Store the last set and the desired cursor properties, so that we only update ! * them when needed. Doing it unnecessary may result in flicker. */ static char_u *last_set_cursor_color = NULL; static char_u *desired_cursor_color = NULL; static int last_set_cursor_shape = -1; --- 194,209 ---- static void handle_postponed_scrollback(term_T *term); ! // The character that we know (or assume) that the terminal expects for the ! // backspace key. static int term_backspace_char = BS; ! // "Terminal" highlight group colors. static int term_default_cterm_fg = -1; static int term_default_cterm_bg = -1; ! // Store the last set and the desired cursor properties, so that we only update ! // them when needed. Doing it unnecessary may result in flicker. static char_u *last_set_cursor_color = NULL; static char_u *desired_cursor_color = NULL; static int last_set_cursor_shape = -1; *************** *** 212,220 **** static int desired_cursor_blink = -1; ! /************************************** ! * 1. Generic code for all systems. ! */ static int cursor_color_equal(char_u *lhs_color, char_u *rhs_color) --- 212,219 ---- static int desired_cursor_blink = -1; ! /////////////////////////////////////// ! // 1. Generic code for all systems. static int cursor_color_equal(char_u *lhs_color, char_u *rhs_color) *************** *** 259,265 **** { char_u *p = vim_strchr(wp->w_p_tws, 'x'); ! /* Syntax of value was already checked when it's set. */ if (p == NULL) { minsize = TRUE; --- 258,264 ---- { char_u *p = vim_strchr(wp->w_p_tws, 'x'); ! // Syntax of value was already checked when it's set. if (p == NULL) { minsize = TRUE; *************** *** 280,287 **** #ifdef FEAT_GUI if (term->tl_system) { ! /* Use the whole screen for the system command. However, it will start ! * at the command line and scroll up as needed, using tl_toprow. */ term->tl_rows = Rows; term->tl_cols = Columns; return; --- 279,286 ---- #ifdef FEAT_GUI if (term->tl_system) { ! // Use the whole screen for the system command. However, it will start ! // at the command line and scroll up as needed, using tl_toprow. term->tl_rows = Rows; term->tl_cols = Columns; return; *************** *** 326,337 **** setup_job_options(jobopt_T *opt, int rows, int cols) { #ifndef MSWIN ! /* Win32: Redirecting the job output won't work, thus always connect stdout ! * here. */ if (!(opt->jo_set & JO_OUT_IO)) #endif { ! /* Connect stdout to the terminal. */ opt->jo_io[PART_OUT] = JIO_BUFFER; opt->jo_io_buf[PART_OUT] = curbuf->b_fnum; opt->jo_modifiable[PART_OUT] = 0; --- 325,336 ---- setup_job_options(jobopt_T *opt, int rows, int cols) { #ifndef MSWIN ! // Win32: Redirecting the job output won't work, thus always connect stdout ! // here. if (!(opt->jo_set & JO_OUT_IO)) #endif { ! // Connect stdout to the terminal. opt->jo_io[PART_OUT] = JIO_BUFFER; opt->jo_io_buf[PART_OUT] = curbuf->b_fnum; opt->jo_modifiable[PART_OUT] = 0; *************** *** 339,350 **** } #ifndef MSWIN ! /* Win32: Redirecting the job output won't work, thus always connect stderr ! * here. */ if (!(opt->jo_set & JO_ERR_IO)) #endif { ! /* Connect stderr to the terminal. */ opt->jo_io[PART_ERR] = JIO_BUFFER; opt->jo_io_buf[PART_ERR] = curbuf->b_fnum; opt->jo_modifiable[PART_ERR] = 0; --- 338,349 ---- } #ifndef MSWIN ! // Win32: Redirecting the job output won't work, thus always connect stderr ! // here. if (!(opt->jo_set & JO_ERR_IO)) #endif { ! // Connect stderr to the terminal. opt->jo_io[PART_ERR] = JIO_BUFFER; opt->jo_io_buf[PART_ERR] = curbuf->b_fnum; opt->jo_modifiable[PART_ERR] = 0; *************** *** 384,391 **** ++curbuf->b_nwindows; } ! /* Wiping out the buffer will also close the window and call ! * free_terminal(). */ do_buffer(DOBUF_WIPE, DOBUF_FIRST, FORWARD, buf->b_fnum, TRUE); } --- 383,390 ---- ++curbuf->b_nwindows; } ! // Wiping out the buffer will also close the window and call ! // free_terminal(). do_buffer(DOBUF_WIPE, DOBUF_FIRST, FORWARD, buf->b_fnum, TRUE); } *************** *** 440,446 **** vim_memset(&split_ea, 0, sizeof(split_ea)); if (opt->jo_curwin) { ! /* Create a new buffer in the current window. */ if (!can_abandon(curbuf, flags & TERM_START_FORCEIT)) { no_write_message(); --- 439,445 ---- vim_memset(&split_ea, 0, sizeof(split_ea)); if (opt->jo_curwin) { ! // Create a new buffer in the current window. if (!can_abandon(curbuf, flags & TERM_START_FORCEIT)) { no_write_message(); *************** *** 460,467 **** { buf_T *buf; ! /* Create a new buffer without a window. Make it the current buffer for ! * a moment to be able to do the initialisations. */ buf = buflist_new((char_u *)"", NULL, (linenr_T)0, BLN_NEW | BLN_LISTED); if (buf == NULL || ml_open(buf) == FAIL) --- 459,466 ---- { buf_T *buf; ! // Create a new buffer without a window. Make it the current buffer for ! // a moment to be able to do the initialisations. buf = buflist_new((char_u *)"", NULL, (linenr_T)0, BLN_NEW | BLN_LISTED); if (buf == NULL || ml_open(buf) == FAIL) *************** *** 477,483 **** } else { ! /* Open a new window or tab. */ split_ea.cmdidx = CMD_new; split_ea.cmd = (char_u *)"new"; split_ea.arg = (char_u *)""; --- 476,482 ---- } else { ! // Open a new window or tab. split_ea.cmdidx = CMD_new; split_ea.cmd = (char_u *)"new"; split_ea.arg = (char_u *)""; *************** *** 497,503 **** ex_splitview(&split_ea); if (curwin == old_curwin) { ! /* split failed */ vim_free(term); return NULL; } --- 496,502 ---- ex_splitview(&split_ea); if (curwin == old_curwin) { ! // split failed vim_free(term); return NULL; } *************** *** 507,521 **** if (!opt->jo_hidden) { ! /* Only one size was taken care of with :new, do the other one. With ! * "curwin" both need to be done. */ if (opt->jo_term_rows > 0 && (opt->jo_curwin || vertical)) win_setheight(opt->jo_term_rows); if (opt->jo_term_cols > 0 && (opt->jo_curwin || !vertical)) win_setwidth(opt->jo_term_cols); } ! /* Link the new terminal in the list of active terminals. */ term->tl_next = first_term; first_term = term; --- 506,520 ---- if (!opt->jo_hidden) { ! // Only one size was taken care of with :new, do the other one. With ! // "curwin" both need to be done. if (opt->jo_term_rows > 0 && (opt->jo_curwin || vertical)) win_setheight(opt->jo_term_rows); if (opt->jo_term_cols > 0 && (opt->jo_curwin || !vertical)) win_setwidth(opt->jo_term_cols); } ! // Link the new terminal in the list of active terminals. term->tl_next = first_term; first_term = term; *************** *** 549,556 **** for (i = 0; p != NULL; ++i) { ! /* Prepend a ! to the command name to avoid the buffer name equals ! * the executable, otherwise ":w!" would overwrite it. */ if (i == 0) vim_snprintf((char *)p, len, "!%s", cmd); else --- 548,555 ---- for (i = 0; p != NULL; ++i) { ! // Prepend a ! to the command name to avoid the buffer name equals ! // the executable, otherwise ":w!" would overwrite it. if (i == 0) vim_snprintf((char *)p, len, "!%s", cmd); else *************** *** 576,583 **** // Avoid that 'buftype' is reset when this buffer is entered. curbuf->b_p_initialized = TRUE; ! /* Mark the buffer as not modifiable. It can only be made modifiable after ! * the job finished. */ curbuf->b_p_ma = FALSE; set_term_and_win_size(term); --- 575,582 ---- // Avoid that 'buftype' is reset when this buffer is entered. curbuf->b_p_initialized = TRUE; ! // Mark the buffer as not modifiable. It can only be made modifiable after ! // the job finished. curbuf->b_p_ma = FALSE; set_term_and_win_size(term); *************** *** 590,596 **** return curbuf; #if defined(FEAT_SESSION) ! /* Remember the command for the session file. */ if (opt->jo_term_norestore || argv != NULL) { term->tl_command = vim_strsave((char_u *)"NONE"); --- 589,595 ---- return curbuf; #if defined(FEAT_SESSION) ! // Remember the command for the session file. if (opt->jo_term_norestore || argv != NULL) { term->tl_command = vim_strsave((char_u *)"NONE"); *************** *** 647,653 **** else term->tl_api = vim_strsave((char_u *)"Tapi_"); ! /* System dependent: setup the vterm and maybe start the job in it. */ if (argv == NULL && argvar->v_type == VAR_STRING && argvar->vval.v_string != NULL --- 646,652 ---- else term->tl_api = vim_strsave((char_u *)"Tapi_"); ! // System dependent: setup the vterm and maybe start the job in it. if (argv == NULL && argvar->v_type == VAR_STRING && argvar->vval.v_string != NULL *************** *** 659,678 **** newbuf = curbuf; if (res == OK) { ! /* Get and remember the size we ended up with. Update the pty. */ vterm_get_size(term->tl_vterm, &term->tl_rows, &term->tl_cols); term_report_winsize(term, term->tl_rows, term->tl_cols); #ifdef FEAT_GUI if (term->tl_system) { ! /* display first line below typed command */ term->tl_toprow = msg_row + 1; term->tl_dirty_row_end = 0; } #endif ! /* Make sure we don't get stuck on sending keys to the job, it leads to ! * a deadlock if the job is waiting for Vim to read. */ channel_set_nonblock(term->tl_job->jv_channel, PART_IN); if (old_curbuf != NULL) --- 658,677 ---- newbuf = curbuf; if (res == OK) { ! // Get and remember the size we ended up with. Update the pty. vterm_get_size(term->tl_vterm, &term->tl_rows, &term->tl_cols); term_report_winsize(term, term->tl_rows, term->tl_cols); #ifdef FEAT_GUI if (term->tl_system) { ! // display first line below typed command term->tl_toprow = msg_row + 1; term->tl_dirty_row_end = 0; } #endif ! // Make sure we don't get stuck on sending keys to the job, it leads to ! // a deadlock if the job is waiting for Vim to read. channel_set_nonblock(term->tl_job->jv_channel, PART_IN); if (old_curbuf != NULL) *************** *** 816,832 **** } if (*cmd == NUL) { ! /* Make a copy of 'shell', an autocommand may change the option. */ tofree = cmd = vim_strsave(p_sh); ! /* default to close when the shell exits */ if (opt.jo_term_finish == NUL) opt.jo_term_finish = 'c'; } if (eap->addr_count > 0) { ! /* Write lines from current buffer to the job. */ opt.jo_set |= JO_IN_IO | JO_IN_BUF | JO_IN_TOP | JO_IN_BOT; opt.jo_io[PART_IN] = JIO_BUFFER; opt.jo_io_buf[PART_IN] = curbuf->b_fnum; --- 815,831 ---- } if (*cmd == NUL) { ! // Make a copy of 'shell', an autocommand may change the option. tofree = cmd = vim_strsave(p_sh); ! // default to close when the shell exits if (opt.jo_term_finish == NUL) opt.jo_term_finish = 'c'; } if (eap->addr_count > 0) { ! // Write lines from current buffer to the job. opt.jo_set |= JO_IN_IO | JO_IN_BUF | JO_IN_TOP | JO_IN_BOT; opt.jo_io[PART_IN] = JIO_BUFFER; opt.jo_io_buf[PART_IN] = curbuf->b_fnum; *************** *** 886,894 **** { term_T *term = wp->w_buffer->b_term; ! /* Create the terminal and run the command. This is not without ! * risk, but let's assume the user only creates a session when this ! * will be OK. */ if (fprintf(fd, "terminal ++curwin ++cols=%d ++rows=%d ", term->tl_cols, term->tl_rows) < 0) return FAIL; --- 885,893 ---- { term_T *term = wp->w_buffer->b_term; ! // Create the terminal and run the command. This is not without ! // risk, but let's assume the user only creates a session when this ! // will be OK. if (fprintf(fd, "terminal ++curwin ++cols=%d ++rows=%d ", term->tl_cols, term->tl_rows) < 0) return FAIL; *************** *** 1044,1050 **** vterm_input_write(vterm, (char *)msg, len); ! /* flush vterm buffer when vterm responded to control sequence */ if (prevlen != vterm_output_get_buffer_current(vterm)) { char buf[KEY_BUF_LEN]; --- 1043,1049 ---- vterm_input_write(vterm, (char *)msg, len); ! // flush vterm buffer when vterm responded to control sequence if (prevlen != vterm_output_get_buffer_current(vterm)) { char buf[KEY_BUF_LEN]; *************** *** 1055,1061 **** (char_u *)buf, (int)curlen, NULL); } ! /* this invokes the damage callbacks */ vterm_screen_flush_damage(vterm_obtain_screen(vterm)); } --- 1054,1060 ---- (char_u *)buf, (int)curlen, NULL); } ! // this invokes the damage callbacks vterm_screen_flush_damage(vterm_obtain_screen(vterm)); } *************** *** 1097,1104 **** term_T *term = buffer->b_term; #ifdef MSWIN ! /* Win32: Cannot redirect output of the job, intercept it here and write to ! * the file. */ if (term->tl_out_fd != NULL) { ch_log(channel, "Writing %d bytes to output file", (int)len); --- 1096,1103 ---- term_T *term = buffer->b_term; #ifdef MSWIN ! // Win32: Cannot redirect output of the job, intercept it here and write to ! // the file. if (term->tl_out_fd != NULL) { ch_log(channel, "Writing %d bytes to output file", (int)len); *************** *** 1118,1131 **** #ifdef FEAT_GUI if (term->tl_system) { ! /* show system output, scrolling up the screen as needed */ update_system_term(term); update_cursor(term, TRUE); } else #endif ! /* In Terminal-Normal mode we are displaying the buffer, not the terminal ! * contents, thus no screen update is needed. */ if (!term->tl_normal_mode) { // Don't use update_screen() when editing the command line, it gets --- 1117,1130 ---- #ifdef FEAT_GUI if (term->tl_system) { ! // show system output, scrolling up the screen as needed update_system_term(term); update_cursor(term, TRUE); } else #endif ! // In Terminal-Normal mode we are displaying the buffer, not the terminal ! // contents, thus no screen update is needed. if (!term->tl_normal_mode) { // Don't use update_screen() when editing the command line, it gets *************** *** 1135,1142 **** if (buffer == curbuf && (State & CMDLINE) == 0) { update_screen(VALID_NO_UPDATE); ! /* update_screen() can be slow, check the terminal wasn't closed ! * already */ if (buffer == curbuf && curbuf->b_term != NULL) update_cursor(curbuf->b_term, TRUE); } --- 1134,1141 ---- if (buffer == curbuf && (State & CMDLINE) == 0) { update_screen(VALID_NO_UPDATE); ! // update_screen() can be slow, check the terminal wasn't closed ! // already if (buffer == curbuf && curbuf->b_term != NULL) update_cursor(curbuf->b_term, TRUE); } *************** *** 1171,1193 **** term_mouse_click(VTerm *vterm, int key) { #if defined(FEAT_CLIPBOARD) ! /* For modeless selection mouse drag and release events are ignored, unless ! * they are preceded with a mouse down event */ static int ignore_drag_release = TRUE; VTermMouseState mouse_state; vterm_state_get_mousestate(vterm_obtain_state(vterm), &mouse_state); if (mouse_state.flags == 0) { ! /* Terminal is not using the mouse, use modeless selection. */ switch (key) { case K_LEFTDRAG: case K_LEFTRELEASE: case K_RIGHTDRAG: case K_RIGHTRELEASE: ! /* Ignore drag and release events when the button-down wasn't ! * seen before. */ if (ignore_drag_release) { int save_mouse_col, save_mouse_row; --- 1170,1192 ---- term_mouse_click(VTerm *vterm, int key) { #if defined(FEAT_CLIPBOARD) ! // For modeless selection mouse drag and release events are ignored, unless ! // they are preceded with a mouse down event static int ignore_drag_release = TRUE; VTermMouseState mouse_state; vterm_state_get_mousestate(vterm_obtain_state(vterm), &mouse_state); if (mouse_state.flags == 0) { ! // Terminal is not using the mouse, use modeless selection. switch (key) { case K_LEFTDRAG: case K_LEFTRELEASE: case K_RIGHTDRAG: case K_RIGHTRELEASE: ! // Ignore drag and release events when the button-down wasn't ! // seen before. if (ignore_drag_release) { int save_mouse_col, save_mouse_row; *************** *** 1195,1202 **** if (enter_mouse_col < 0) break; ! /* mouse click in the window gave us focus, handle that ! * click now */ save_mouse_col = mouse_col; save_mouse_row = mouse_row; mouse_col = enter_mouse_col; --- 1194,1201 ---- if (enter_mouse_col < 0) break; ! // mouse click in the window gave us focus, handle that ! // click now save_mouse_col = mouse_col; save_mouse_row = mouse_row; mouse_col = enter_mouse_col; *************** *** 1205,1218 **** mouse_col = save_mouse_col; mouse_row = save_mouse_row; } ! /* FALLTHROUGH */ case K_LEFTMOUSE: case K_RIGHTMOUSE: if (key == K_LEFTRELEASE || key == K_RIGHTRELEASE) ignore_drag_release = TRUE; else ignore_drag_release = FALSE; ! /* Should we call mouse_has() here? */ if (clip_star.available) { int button, is_click, is_drag; --- 1204,1217 ---- mouse_col = save_mouse_col; mouse_row = save_mouse_row; } ! // FALLTHROUGH case K_LEFTMOUSE: case K_RIGHTMOUSE: if (key == K_LEFTRELEASE || key == K_RIGHTRELEASE) ignore_drag_release = TRUE; else ignore_drag_release = FALSE; ! // Should we call mouse_has() here? if (clip_star.available) { int button, is_click, is_drag; *************** *** 1222,1228 **** if (mouse_model_popup() && button == MOUSE_LEFT && (mod_mask & MOD_MASK_SHIFT)) { ! /* Translate shift-left to right button. */ button = MOUSE_RIGHT; mod_mask &= ~MOD_MASK_SHIFT; } --- 1221,1227 ---- if (mouse_model_popup() && button == MOUSE_LEFT && (mod_mask & MOD_MASK_SHIFT)) { ! // Translate shift-left to right button. button = MOUSE_RIGHT; mod_mask &= ~MOD_MASK_SHIFT; } *************** *** 1274,1283 **** switch (c) { ! /* don't use VTERM_KEY_ENTER, it may do an unwanted conversion */ ! /* don't use VTERM_KEY_BACKSPACE, it always ! * becomes 0x7f DEL */ case K_BS: c = term_backspace_char; break; case ESC: key = VTERM_KEY_ESCAPE; break; --- 1273,1282 ---- switch (c) { ! // don't use VTERM_KEY_ENTER, it may do an unwanted conversion ! // don't use VTERM_KEY_BACKSPACE, it always ! // becomes 0x7f DEL case K_BS: c = term_backspace_char; break; case ESC: key = VTERM_KEY_ESCAPE; break; *************** *** 1318,1333 **** case K_K7: key = VTERM_KEY_KP_7; break; case K_K8: key = VTERM_KEY_KP_8; break; case K_K9: key = VTERM_KEY_KP_9; break; ! case K_KDEL: key = VTERM_KEY_DEL; break; /* TODO */ case K_KDIVIDE: key = VTERM_KEY_KP_DIVIDE; break; ! case K_KEND: key = VTERM_KEY_KP_1; break; /* TODO */ case K_KENTER: key = VTERM_KEY_KP_ENTER; break; ! case K_KHOME: key = VTERM_KEY_KP_7; break; /* TODO */ ! case K_KINS: key = VTERM_KEY_KP_0; break; /* TODO */ case K_KMINUS: key = VTERM_KEY_KP_MINUS; break; case K_KMULTIPLY: key = VTERM_KEY_KP_MULT; break; ! case K_KPAGEDOWN: key = VTERM_KEY_KP_3; break; /* TODO */ ! case K_KPAGEUP: key = VTERM_KEY_KP_9; break; /* TODO */ case K_KPLUS: key = VTERM_KEY_KP_PLUS; break; case K_KPOINT: key = VTERM_KEY_KP_PERIOD; break; case K_LEFT: key = VTERM_KEY_LEFT; break; --- 1317,1332 ---- case K_K7: key = VTERM_KEY_KP_7; break; case K_K8: key = VTERM_KEY_KP_8; break; case K_K9: key = VTERM_KEY_KP_9; break; ! case K_KDEL: key = VTERM_KEY_DEL; break; // TODO case K_KDIVIDE: key = VTERM_KEY_KP_DIVIDE; break; ! case K_KEND: key = VTERM_KEY_KP_1; break; // TODO case K_KENTER: key = VTERM_KEY_KP_ENTER; break; ! case K_KHOME: key = VTERM_KEY_KP_7; break; // TODO ! case K_KINS: key = VTERM_KEY_KP_0; break; // TODO case K_KMINUS: key = VTERM_KEY_KP_MINUS; break; case K_KMULTIPLY: key = VTERM_KEY_KP_MULT; break; ! case K_KPAGEDOWN: key = VTERM_KEY_KP_3; break; // TODO ! case K_KPAGEUP: key = VTERM_KEY_KP_9; break; // TODO case K_KPLUS: key = VTERM_KEY_KP_PLUS; break; case K_KPOINT: key = VTERM_KEY_KP_PERIOD; break; case K_LEFT: key = VTERM_KEY_LEFT; break; *************** *** 1423,1435 **** * - Write output to channel. */ if (key != VTERM_KEY_NONE) ! /* Special key, let vterm convert it. */ vterm_keyboard_key(vterm, key, mod); else if (!other) ! /* Normal character, let vterm convert it. */ vterm_keyboard_unichar(vterm, c, mod); ! /* Read back the converted escape sequence. */ return (int)vterm_output_read(vterm, buf, KEY_BUF_LEN); } --- 1422,1434 ---- * - Write output to channel. */ if (key != VTERM_KEY_NONE) ! // Special key, let vterm convert it. vterm_keyboard_key(vterm, key, mod); else if (!other) ! // Normal character, let vterm convert it. vterm_keyboard_unichar(vterm, c, mod); ! // Read back the converted escape sequence. return (int)vterm_output_read(vterm, buf, KEY_BUF_LEN); } *************** *** 1441,1448 **** static int term_job_running_check(term_T *term, int check_job_status) { ! /* Also consider the job finished when the channel is closed, to avoid a ! * race condition when updating the title. */ if (term != NULL && term->tl_job != NULL && channel_is_open(term->tl_job->jv_channel)) --- 1440,1447 ---- static int term_job_running_check(term_T *term, int check_job_status) { ! // Also consider the job finished when the channel is closed, to avoid a ! // race condition when updating the title. if (term != NULL && term->tl_job != NULL && channel_is_open(term->tl_job->jv_channel)) *************** *** 1475,1482 **** int term_none_open(term_T *term) { ! /* Also consider the job finished when the channel is closed, to avoid a ! * race condition when updating the title. */ return term != NULL && term->tl_job != NULL && channel_is_open(term->tl_job->jv_channel) --- 1474,1481 ---- int term_none_open(term_T *term) { ! // Also consider the job finished when the channel is closed, to avoid a ! // race condition when updating the title. return term != NULL && term->tl_job != NULL && channel_is_open(term->tl_job->jv_channel) *************** *** 1569,1575 **** ml_append_buf(term->tl_buffer, lnum, text, len + 1, FALSE); if (empty) { ! /* Delete the empty line that was in the empty buffer. */ curbuf = buf; ml_delete(1, FALSE); curbuf = curwin->w_buffer; --- 1568,1574 ---- ml_append_buf(term->tl_buffer, lnum, text, len + 1, FALSE); if (empty) { ! // Delete the empty line that was in the empty buffer. curbuf = buf; ml_delete(1, FALSE); curbuf = curwin->w_buffer; *************** *** 1588,1594 **** static int equal_celattr(cellattr_T *a, cellattr_T *b) { ! /* Comparing the colors should be sufficient. */ return a->fg.red == b->fg.red && a->fg.green == b->fg.green && a->fg.blue == b->fg.blue --- 1587,1593 ---- static int equal_celattr(cellattr_T *a, cellattr_T *b) { ! // Comparing the colors should be sufficient. return a->fg.red == b->fg.red && a->fg.green == b->fg.green && a->fg.blue == b->fg.blue *************** *** 1671,1678 **** ch_log(term->tl_job == NULL ? NULL : term->tl_job->jv_channel, "Adding terminal window snapshot to buffer"); ! /* First remove the lines that were appended before, they might be ! * outdated. */ cleanup_scrollback(term); screen = vterm_obtain_screen(term->tl_vterm); --- 1670,1677 ---- ch_log(term->tl_job == NULL ? NULL : term->tl_job->jv_channel, "Adding terminal window snapshot to buffer"); ! // First remove the lines that were appended before, they might be ! // outdated. cleanup_scrollback(term); screen = vterm_obtain_screen(term->tl_vterm); *************** *** 1688,1694 **** new_fill_attr = term->tl_default_color; } else ! /* Assume the last attr is the filler attr. */ cell2cellattr(&cell, &new_fill_attr); if (len == 0 && equal_celattr(&new_fill_attr, &fill_attr)) --- 1687,1693 ---- new_fill_attr = term->tl_default_color; } else ! // Assume the last attr is the filler attr. cell2cellattr(&cell, &new_fill_attr); if (len == 0 && equal_celattr(&new_fill_attr, &fill_attr)) *************** *** 1697,1703 **** { while (lines_skipped > 0) { ! /* Line was skipped, add an empty line. */ --lines_skipped; if (add_empty_scrollback(term, &fill_attr, 0) == OK) add_scrollback_line_to_buffer(term, (char_u *)"", 0); --- 1696,1702 ---- { while (lines_skipped > 0) { ! // Line was skipped, add an empty line. --lines_skipped; if (add_empty_scrollback(term, &fill_attr, 0) == OK) add_scrollback_line_to_buffer(term, (char_u *)"", 0); *************** *** 1793,1805 **** if (term->tl_vterm == NULL) return; ! /* Update the snapshot only if something changes or the buffer does not ! * have all the lines. */ if (term->tl_dirty_snapshot || term->tl_buffer->b_ml.ml_line_count <= term->tl_scrollback_scrolled) update_snapshot(term); ! /* Obtain the current background color. */ vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm), &term->tl_default_color.fg, &term->tl_default_color.bg); --- 1792,1804 ---- if (term->tl_vterm == NULL) return; ! // Update the snapshot only if something changes or the buffer does not ! // have all the lines. if (term->tl_dirty_snapshot || term->tl_buffer->b_ml.ml_line_count <= term->tl_scrollback_scrolled) update_snapshot(term); ! // Obtain the current background color. vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm), &term->tl_default_color.fg, &term->tl_default_color.bg); *************** *** 1894,1911 **** set_terminal_mode(term, TRUE); ! /* Append the current terminal contents to the buffer. */ may_move_terminal_to_buffer(term, TRUE); ! /* Move the window cursor to the position of the cursor in the ! * terminal. */ curwin->w_cursor.lnum = term->tl_scrollback_scrolled + term->tl_cursor_pos.row + 1; check_cursor(); if (coladvance(term->tl_cursor_pos.col) == FAIL) coladvance(MAXCOL); ! /* Display the same lines as in the terminal. */ curwin->w_topline = term->tl_scrollback_scrolled + 1; } --- 1893,1910 ---- set_terminal_mode(term, TRUE); ! // Append the current terminal contents to the buffer. may_move_terminal_to_buffer(term, TRUE); ! // Move the window cursor to the position of the cursor in the ! // terminal. curwin->w_cursor.lnum = term->tl_scrollback_scrolled + term->tl_cursor_pos.row + 1; check_cursor(); if (coladvance(term->tl_cursor_pos.col) == FAIL) coladvance(MAXCOL); ! // Display the same lines as in the terminal. curwin->w_topline = term->tl_scrollback_scrolled + 1; } *************** *** 1979,1985 **** size_t len; int dragging_outside = FALSE; ! /* Catch keys that need to be handled as in Normal mode. */ switch (c) { case NUL: --- 1978,1984 ---- size_t len; int dragging_outside = FALSE; ! // Catch keys that need to be handled as in Normal mode. switch (c) { case NUL: *************** *** 2002,2008 **** case K_X1DRAG: case K_X2DRAG: dragging_outside = mouse_was_outside; ! /* FALLTHROUGH */ case K_LEFTMOUSE: case K_LEFTMOUSE_NM: case K_LEFTRELEASE: --- 2001,2007 ---- case K_X1DRAG: case K_X2DRAG: dragging_outside = mouse_was_outside; ! // FALLTHROUGH case K_LEFTMOUSE: case K_LEFTMOUSE_NM: case K_LEFTRELEASE: *************** *** 2027,2034 **** || mouse_col >= W_ENDCOL(curwin) || dragging_outside) { ! /* click or scroll outside the current window or on status line ! * or vertical separator */ if (typed) { stuffcharReadbuff(c); --- 2026,2033 ---- || mouse_col >= W_ENDCOL(curwin) || dragging_outside) { ! // click or scroll outside the current window or on status line ! // or vertical separator if (typed) { stuffcharReadbuff(c); *************** *** 2080,2093 **** clear_showcmd(); #endif if (!term_use_loop()) ! /* job finished while waiting for a character */ return; ! /* CTRL-W "= prompt for expression to evaluate. */ if (c == '=' && get_expr_register() != '=') return; if (!term_use_loop()) ! /* job finished while waiting for a character */ return; l = (list_T *)get_reg_contents(c, GREG_LIST); --- 2079,2092 ---- clear_showcmd(); #endif if (!term_use_loop()) ! // job finished while waiting for a character return; ! // CTRL-W "= prompt for expression to evaluate. if (c == '=' && get_expr_register() != '=') return; if (!term_use_loop()) ! // job finished while waiting for a character return; l = (list_T *)get_reg_contents(c, GREG_LIST); *************** *** 2162,2168 **** entry.blinkoff = 250; } ! /* The "Terminal" highlight group overrules the defaults. */ id = syn_name2id((char_u *)"Terminal"); if (id != 0) { --- 2161,2167 ---- entry.blinkoff = 250; } ! // The "Terminal" highlight group overrules the defaults. id = syn_name2id((char_u *)"Terminal"); if (id != 0) { *************** *** 2200,2206 **** last_set_cursor_blink = desired_cursor_blink; term_cursor_color(cursor_color_get(desired_cursor_color)); if (desired_cursor_shape == -1 || desired_cursor_blink == -1) ! /* this will restore the initial cursor style, if possible */ ui_cursor_shape_forced(TRUE); else term_cursor_shape(desired_cursor_shape, desired_cursor_blink); --- 2199,2205 ---- last_set_cursor_blink = desired_cursor_blink; term_cursor_color(cursor_color_get(desired_cursor_color)); if (desired_cursor_shape == -1 || desired_cursor_blink == -1) ! // this will restore the initial cursor style, if possible ui_cursor_shape_forced(TRUE); else term_cursor_shape(desired_cursor_shape, desired_cursor_blink); *************** *** 2214,2221 **** may_set_cursor_props(term_T *term) { #ifdef FEAT_GUI ! /* For the GUI the cursor properties are obtained with ! * term_get_cursor_shape(). */ if (gui.in_use) return; #endif --- 2213,2220 ---- may_set_cursor_props(term_T *term) { #ifdef FEAT_GUI ! // For the GUI the cursor properties are obtained with ! // term_get_cursor_shape(). if (gui.in_use) return; #endif *************** *** 2343,2352 **** #endif int restore_cursor = FALSE; ! /* Remember the terminal we are sending keys to. However, the terminal ! * might be closed while waiting for a character, e.g. typing "exit" in a ! * shell and ++close was used. Therefore use curbuf->b_term instead of a ! * stored reference. */ in_terminal_loop = curbuf->b_term; if (*curwin->w_p_twk != NUL) --- 2342,2351 ---- #endif int restore_cursor = FALSE; ! // Remember the terminal we are sending keys to. However, the terminal ! // might be closed while waiting for a character, e.g. typing "exit" in a ! // shell and ++close was used. Therefore use curbuf->b_term instead of a ! // stored reference. in_terminal_loop = curbuf->b_term; if (*curwin->w_p_twk != NUL) *************** *** 2369,2375 **** if (update_screen(0) == FAIL) break; if (!term_use_loop_check(TRUE) || in_terminal_loop != curbuf->b_term) ! /* job finished while redrawing */ break; update_cursor(curbuf->b_term, FALSE); --- 2368,2374 ---- if (update_screen(0) == FAIL) break; if (!term_use_loop_check(TRUE) || in_terminal_loop != curbuf->b_term) ! // job finished while redrawing break; update_cursor(curbuf->b_term, FALSE); *************** *** 2378,2385 **** raw_c = term_vgetc(); if (!term_use_loop_check(TRUE) || in_terminal_loop != curbuf->b_term) { ! /* Job finished while waiting for a character. Push back the ! * received character. */ if (raw_c != K_IGNORE) vungetc(raw_c); break; --- 2377,2384 ---- raw_c = term_vgetc(); if (!term_use_loop_check(TRUE) || in_terminal_loop != curbuf->b_term) { ! // Job finished while waiting for a character. Push back the ! // received character. if (raw_c != K_IGNORE) vungetc(raw_c); break; *************** *** 2398,2417 **** { ttyinfo_T info; ! /* Get the current backspace character of the pty. */ if (get_tty_info(tty_fd, &info) == OK) term_backspace_char = info.backspace; } #endif #ifdef MSWIN ! /* On Windows winpty handles CTRL-C, don't send a CTRL_C_EVENT. ! * Use CTRL-BREAK to kill the job. */ if (ctrl_break_was_pressed) mch_signal_job(curbuf->b_term->tl_job, (char_u *)"kill"); #endif ! /* Was either CTRL-W (termwinkey) or CTRL-\ pressed? ! * Not in a system terminal. */ if ((c == (termwinkey == 0 ? Ctrl_W : termwinkey) || c == Ctrl_BSL) #ifdef FEAT_GUI && !curbuf->b_term->tl_system --- 2397,2416 ---- { ttyinfo_T info; ! // Get the current backspace character of the pty. if (get_tty_info(tty_fd, &info) == OK) term_backspace_char = info.backspace; } #endif #ifdef MSWIN ! // On Windows winpty handles CTRL-C, don't send a CTRL_C_EVENT. ! // Use CTRL-BREAK to kill the job. if (ctrl_break_was_pressed) mch_signal_job(curbuf->b_term->tl_job, (char_u *)"kill"); #endif ! // Was either CTRL-W (termwinkey) or CTRL-\ pressed? ! // Not in a system terminal. if ((c == (termwinkey == 0 ? Ctrl_W : termwinkey) || c == Ctrl_BSL) #ifdef FEAT_GUI && !curbuf->b_term->tl_system *************** *** 2434,2447 **** #endif if (!term_use_loop_check(TRUE) || in_terminal_loop != curbuf->b_term) ! /* job finished while waiting for a character */ break; if (prev_c == Ctrl_BSL) { if (c == Ctrl_N) { ! /* CTRL-\ CTRL-N : go to Terminal-Normal mode. */ term_enter_normal_mode(); ret = FAIL; goto theend; --- 2433,2446 ---- #endif if (!term_use_loop_check(TRUE) || in_terminal_loop != curbuf->b_term) ! // job finished while waiting for a character break; if (prev_c == Ctrl_BSL) { if (c == Ctrl_N) { ! // CTRL-\ CTRL-N : go to Terminal-Normal mode. term_enter_normal_mode(); ret = FAIL; goto theend; *************** *** 2453,2475 **** } else if (c == Ctrl_C) { ! /* "CTRL-W CTRL-C" or 'termwinkey' CTRL-C: end the job */ mch_signal_job(curbuf->b_term->tl_job, (char_u *)"kill"); } else if (c == '.') { ! /* "CTRL-W .": send CTRL-W to the job */ ! /* "'termwinkey' .": send 'termwinkey' to the job */ raw_c = ctrl_to_raw_c(termwinkey == 0 ? Ctrl_W : termwinkey); } else if (c == Ctrl_BSL) { ! /* "CTRL-W CTRL-\": send CTRL-\ to the job */ raw_c = ctrl_to_raw_c(Ctrl_BSL); } else if (c == 'N') { ! /* CTRL-W N : go to Terminal-Normal mode. */ term_enter_normal_mode(); ret = FAIL; goto theend; --- 2452,2474 ---- } else if (c == Ctrl_C) { ! // "CTRL-W CTRL-C" or 'termwinkey' CTRL-C: end the job mch_signal_job(curbuf->b_term->tl_job, (char_u *)"kill"); } else if (c == '.') { ! // "CTRL-W .": send CTRL-W to the job ! // "'termwinkey' .": send 'termwinkey' to the job raw_c = ctrl_to_raw_c(termwinkey == 0 ? Ctrl_W : termwinkey); } else if (c == Ctrl_BSL) { ! // "CTRL-W CTRL-\": send CTRL-\ to the job raw_c = ctrl_to_raw_c(Ctrl_BSL); } else if (c == 'N') { ! // CTRL-W N : go to Terminal-Normal mode. term_enter_normal_mode(); ret = FAIL; goto theend; *************** *** 2507,2514 **** if (send_keys_to_term(curbuf->b_term, raw_c, mod_mask, TRUE) != OK) { if (raw_c == K_MOUSEMOVE) ! /* We are sure to come back here, don't reset the cursor color ! * and shape to avoid flickering. */ restore_cursor = FALSE; ret = OK; --- 2506,2513 ---- if (send_keys_to_term(curbuf->b_term, raw_c, mod_mask, TRUE) != OK) { if (raw_c == K_MOUSEMOVE) ! // We are sure to come back here, don't reset the cursor color ! // and shape to avoid flickering. restore_cursor = FALSE; ret = OK; *************** *** 2522,2529 **** if (restore_cursor) prepare_restore_cursor_props(); ! /* Move a snapshot of the screen contents to the buffer, so that completion ! * works in other buffers. */ if (curbuf->b_term != NULL && !curbuf->b_term->tl_normal_mode) may_move_terminal_to_buffer(curbuf->b_term, FALSE); --- 2521,2528 ---- if (restore_cursor) prepare_restore_cursor_props(); ! // Move a snapshot of the screen contents to the buffer, so that completion ! // works in other buffers. if (curbuf->b_term != NULL && !curbuf->b_term->tl_normal_mode) may_move_terminal_to_buffer(curbuf->b_term, FALSE); *************** *** 2559,2580 **** switch (color->ansi_index) { case 0: return 0; ! case 1: return lookup_color( 0, fg, boldp) + 1; /* black */ ! case 2: return lookup_color( 4, fg, boldp) + 1; /* dark red */ ! case 3: return lookup_color( 2, fg, boldp) + 1; /* dark green */ ! case 4: return lookup_color( 6, fg, boldp) + 1; /* brown */ ! case 5: return lookup_color( 1, fg, boldp) + 1; /* dark blue */ ! case 6: return lookup_color( 5, fg, boldp) + 1; /* dark magenta */ ! case 7: return lookup_color( 3, fg, boldp) + 1; /* dark cyan */ ! case 8: return lookup_color( 8, fg, boldp) + 1; /* light grey */ ! case 9: return lookup_color(12, fg, boldp) + 1; /* dark grey */ ! case 10: return lookup_color(20, fg, boldp) + 1; /* red */ ! case 11: return lookup_color(16, fg, boldp) + 1; /* green */ ! case 12: return lookup_color(24, fg, boldp) + 1; /* yellow */ ! case 13: return lookup_color(14, fg, boldp) + 1; /* blue */ ! case 14: return lookup_color(22, fg, boldp) + 1; /* magenta */ ! case 15: return lookup_color(18, fg, boldp) + 1; /* cyan */ ! case 16: return lookup_color(26, fg, boldp) + 1; /* white */ } } --- 2558,2579 ---- switch (color->ansi_index) { case 0: return 0; ! case 1: return lookup_color( 0, fg, boldp) + 1; // black ! case 2: return lookup_color( 4, fg, boldp) + 1; // dark red ! case 3: return lookup_color( 2, fg, boldp) + 1; // dark green ! case 4: return lookup_color( 6, fg, boldp) + 1; // brown ! case 5: return lookup_color( 1, fg, boldp) + 1; // dark blue ! case 6: return lookup_color( 5, fg, boldp) + 1; // dark magenta ! case 7: return lookup_color( 3, fg, boldp) + 1; // dark cyan ! case 8: return lookup_color( 8, fg, boldp) + 1; // light grey ! case 9: return lookup_color(12, fg, boldp) + 1; // dark grey ! case 10: return lookup_color(20, fg, boldp) + 1; // red ! case 11: return lookup_color(16, fg, boldp) + 1; // green ! case 12: return lookup_color(24, fg, boldp) + 1; // yellow ! case 13: return lookup_color(14, fg, boldp) + 1; // blue ! case 14: return lookup_color(22, fg, boldp) + 1; // magenta ! case 15: return lookup_color(18, fg, boldp) + 1; // cyan ! case 16: return lookup_color(26, fg, boldp) + 1; // white } } *************** *** 2582,2588 **** { if (red == blue && red == green) { ! /* 24-color greyscale plus white and black */ static int cutoff[23] = { 0x0D, 0x17, 0x21, 0x2B, 0x35, 0x3F, 0x49, 0x53, 0x5D, 0x67, 0x71, 0x7B, 0x85, 0x8F, 0x99, 0xA3, 0xAD, 0xB7, 0xC1, 0xCB, --- 2581,2587 ---- { if (red == blue && red == green) { ! // 24-color greyscale plus white and black static int cutoff[23] = { 0x0D, 0x17, 0x21, 0x2B, 0x35, 0x3F, 0x49, 0x53, 0x5D, 0x67, 0x71, 0x7B, 0x85, 0x8F, 0x99, 0xA3, 0xAD, 0xB7, 0xC1, 0xCB, *************** *** 2590,2597 **** int i; if (red < 5) ! return 17; /* 00/00/00 */ ! if (red > 245) /* ff/ff/ff */ return 232; for (i = 0; i < 23; ++i) if (red < cutoff[i]) --- 2589,2596 ---- int i; if (red < 5) ! return 17; // 00/00/00 ! if (red > 245) // ff/ff/ff return 232; for (i = 0; i < 23; ++i) if (red < cutoff[i]) *************** *** 2602,2608 **** static int cutoff[5] = {0x2F, 0x73, 0x9B, 0xC3, 0xEB}; int ri, gi, bi; ! /* 216-color cube */ for (ri = 0; ri < 5; ++ri) if (red < cutoff[ri]) break; --- 2601,2607 ---- static int cutoff[5] = {0x2F, 0x73, 0x9B, 0xC3, 0xEB}; int ri, gi, bi; ! // 216-color cube for (ri = 0; ri < 5; ++ri) if (red < cutoff[ri]) break; *************** *** 2694,2700 **** int fg = color2index(&cellfg, TRUE, &bold); int bg = color2index(&cellbg, FALSE, &bold); ! /* Use the "Terminal" highlighting for the default colors. */ if ((fg == 0 || bg == 0) && t_colors >= 16) { if (fg == 0 && term_default_cterm_fg >= 0) --- 2693,2699 ---- int fg = color2index(&cellfg, TRUE, &bold); int bg = color2index(&cellbg, FALSE, &bold); ! // Use the "Terminal" highlighting for the default colors. if ((fg == 0 || bg == 0) && t_colors >= 16) { if (fg == 0 && term_default_cterm_fg >= 0) *************** *** 2703,2709 **** bg = term_default_cterm_bg + 1; } ! /* with 8 colors set the bold attribute to get a bright foreground */ if (bold == TRUE) attr |= HL_BOLD; return get_cterm_attr_idx(attr, fg, bg); --- 2702,2708 ---- bg = term_default_cterm_bg + 1; } ! // with 8 colors set the bold attribute to get a bright foreground if (bold == TRUE) attr |= HL_BOLD; return get_cterm_attr_idx(attr, fg, bg); *************** *** 2718,2724 **** #ifdef FEAT_TIMERS if (!term->tl_normal_mode) { ! /* Update the snapshot after 100 msec of not getting updates. */ profile_setlimit(100L, &term->tl_timer_due); term->tl_timer_set = TRUE; } --- 2717,2723 ---- #ifdef FEAT_TIMERS if (!term->tl_normal_mode) { ! // Update the snapshot after 100 msec of not getting updates. profile_setlimit(100L, &term->tl_timer_due); term->tl_timer_set = TRUE; } *************** *** 2745,2751 **** VTermScreenCellAttrs attr; int clear_attr; ! /* Set the color to clear lines with. */ vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm), &fg, &bg); vim_memset(&attr, 0, sizeof(attr)); --- 2744,2750 ---- VTermScreenCellAttrs attr; int clear_attr; ! // Set the color to clear lines with. vterm_state_get_default_colors(vterm_obtain_state(term->tl_vterm), &fg, &bg); vim_memset(&attr, 0, sizeof(attr)); *************** *** 2764,2772 **** term_T *term = (term_T *)user; int count = src.start_row - dest.start_row; ! /* Scrolling up is done much more efficiently by deleting lines instead of ! * redrawing the text. But avoid doing this multiple times, postpone until ! * the redraw happens. */ if (dest.start_col == src.start_col && dest.end_col == src.end_col && dest.start_row < src.start_row) --- 2763,2771 ---- term_T *term = (term_T *)user; int count = src.start_row - dest.start_row; ! // Scrolling up is done much more efficiently by deleting lines instead of ! // redrawing the text. But avoid doing this multiple times, postpone until ! // the redraw happens. if (dest.start_col == src.start_col && dest.end_col == src.end_col && dest.start_row < src.start_row) *************** *** 2781,2788 **** term->tl_dirty_row_end = MIN(term->tl_dirty_row_end, dest.end_row); set_dirty_snapshot(term); ! /* Note sure if the scrolling will work correctly, let's do a complete ! * redraw later. */ redraw_buf_later(term->tl_buffer, NOT_VALID); return 1; } --- 2780,2787 ---- term->tl_dirty_row_end = MIN(term->tl_dirty_row_end, dest.end_row); set_dirty_snapshot(term); ! // Note sure if the scrolling will work correctly, let's do a complete ! // redraw later. redraw_buf_later(term->tl_buffer, NOT_VALID); return 1; } *************** *** 2885,2898 **** break; case VTERM_PROP_ALTSCREEN: ! /* TODO: do anything else? */ term->tl_using_altscreen = value->boolean; break; default: break; } ! /* Always return 1, otherwise vterm doesn't store the value internally. */ return 1; } --- 2884,2897 ---- break; case VTERM_PROP_ALTSCREEN: ! // TODO: do anything else? term->tl_using_altscreen = value->boolean; break; default: break; } ! // Always return 1, otherwise vterm doesn't store the value internally. return 1; } *************** *** 2908,2914 **** term->tl_rows = rows; term->tl_cols = cols; if (term->tl_vterm_size_changed) ! /* Size was set by vterm_set_size(), don't set the window size. */ term->tl_vterm_size_changed = FALSE; else { --- 2907,2913 ---- term->tl_rows = rows; term->tl_cols = cols; if (term->tl_vterm_size_changed) ! // Size was set by vterm_set_size(), don't set the window size. term->tl_vterm_size_changed = FALSE; else { *************** *** 3057,3063 **** } ++gap->ga_len; } ! return 0; /* ignored */ } /* --- 3056,3062 ---- } ++gap->ga_len; } ! return 0; // ignored } /* *************** *** 3108,3121 **** } static VTermScreenCallbacks screen_callbacks = { ! handle_damage, /* damage */ ! handle_moverect, /* moverect */ ! handle_movecursor, /* movecursor */ ! handle_settermprop, /* settermprop */ ! NULL, /* bell */ ! handle_resize, /* resize */ ! handle_pushline, /* sb_pushline */ ! NULL /* sb_popline */ }; /* --- 3107,3120 ---- } static VTermScreenCallbacks screen_callbacks = { ! handle_damage, // damage ! handle_moverect, // moverect ! handle_movecursor, // movecursor ! handle_settermprop, // settermprop ! NULL, // bell ! handle_resize, // resize ! handle_pushline, // sb_pushline ! NULL // sb_popline }; /* *************** *** 3126,3132 **** static int term_after_channel_closed(term_T *term) { ! /* Unless in Terminal-Normal mode: clear the vterm. */ if (!term->tl_normal_mode) { int fnum = term->tl_buffer->b_fnum; --- 3125,3131 ---- static int term_after_channel_closed(term_T *term) { ! // Unless in Terminal-Normal mode: clear the vterm. if (!term->tl_normal_mode) { int fnum = term->tl_buffer->b_fnum; *************** *** 3167,3173 **** { char buf[50]; ! /* TODO: use term_opencmd */ ch_log(NULL, "terminal job finished, opening window"); vim_snprintf(buf, sizeof(buf), term->tl_opencmd == NULL --- 3166,3172 ---- { char buf[50]; ! // TODO: use term_opencmd ch_log(NULL, "terminal job finished, opening window"); vim_snprintf(buf, sizeof(buf), term->tl_opencmd == NULL *************** *** 3214,3221 **** if (updating_screen) { ! /* Cannot open or close windows now. Can happen when ! * 'lazyredraw' is set. */ term->tl_channel_recently_closed = TRUE; continue; } --- 3213,3220 ---- if (updating_screen) { ! // Cannot open or close windows now. Can happen when ! // 'lazyredraw' is set. term->tl_channel_recently_closed = TRUE; continue; } *************** *** 3229,3235 **** { redraw_statuslines(); ! /* Need to break out of vgetc(). */ ins_char_typebuf(K_IGNORE); typebuf_was_filled = TRUE; --- 3228,3234 ---- { redraw_statuslines(); ! // Need to break out of vgetc(). ins_char_typebuf(K_IGNORE); typebuf_was_filled = TRUE; *************** *** 3296,3302 **** { int i; ! /* composing chars */ for (i = 0; i < Screen_mco && i + 1 < VTERM_MAX_CHARS_PER_CELL; ++i) { --- 3295,3301 ---- { int i; ! // composing chars for (i = 0; i < Screen_mco && i + 1 < VTERM_MAX_CHARS_PER_CELL; ++i) { *************** *** 3345,3352 **** if (enc_utf8) ScreenLinesUC[off] = NUL; ! /* don't set the second byte to NUL for a DBCS encoding, it ! * has been set above */ if (enc_utf8 || !has_mbyte) ScreenLines[off] = NUL; --- 3344,3351 ---- if (enc_utf8) ScreenLinesUC[off] = NUL; ! // don't set the second byte to NUL for a DBCS encoding, it ! // has been set above if (enc_utf8 || !has_mbyte) ScreenLines[off] = NUL; *************** *** 3367,3373 **** return; screen = vterm_obtain_screen(term->tl_vterm); ! /* Scroll up to make more room for terminal lines if needed. */ while (term->tl_toprow > 0 && (Rows - term->tl_toprow) < term->tl_dirty_row_end) { --- 3366,3372 ---- return; screen = vterm_obtain_screen(term->tl_vterm); ! // Scroll up to make more room for terminal lines if needed. while (term->tl_toprow > 0 && (Rows - term->tl_toprow) < term->tl_dirty_row_end) { *************** *** 3433,3440 **** screen = vterm_obtain_screen(vterm); state = vterm_obtain_state(vterm); ! /* We use NOT_VALID on a resize or scroll, redraw everything then. With ! * SOME_VALID only redraw what was marked dirty. */ if (wp->w_redr_type > SOME_VALID) { term->tl_dirty_row_start = 0; --- 3432,3439 ---- screen = vterm_obtain_screen(vterm); state = vterm_obtain_state(vterm); ! // We use NOT_VALID on a resize or scroll, redraw everything then. With ! // SOME_VALID only redraw what was marked dirty. if (wp->w_redr_type > SOME_VALID) { term->tl_dirty_row_start = 0; *************** *** 3442,3449 **** if (term->tl_postponed_scroll > 0 && term->tl_postponed_scroll < term->tl_rows / 3) ! /* Scrolling is usually faster than redrawing, when there are only ! * a few lines to scroll. */ term_scroll_up(term, 0, term->tl_postponed_scroll); term->tl_postponed_scroll = 0; } --- 3441,3448 ---- if (term->tl_postponed_scroll > 0 && term->tl_postponed_scroll < term->tl_rows / 3) ! // Scrolling is usually faster than redrawing, when there are only ! // a few lines to scroll. term_scroll_up(term, 0, term->tl_postponed_scroll); term->tl_postponed_scroll = 0; } *************** *** 3458,3465 **** newcols = 99999; FOR_ALL_WINDOWS(twp) { ! /* When more than one window shows the same terminal, use the ! * smallest size. */ if (twp->w_buffer == term->tl_buffer) { newrows = MIN(newrows, twp->w_height); --- 3457,3464 ---- newcols = 99999; FOR_ALL_WINDOWS(twp) { ! // When more than one window shows the same terminal, use the ! // smallest size. if (twp->w_buffer == term->tl_buffer) { newrows = MIN(newrows, twp->w_height); *************** *** 3485,3491 **** may_move_terminal_to_buffer(term, FALSE); } ! /* The cursor may have been moved when resizing. */ vterm_state_get_cursorpos(state, &pos); position_cursor(wp, &pos); --- 3484,3490 ---- may_move_terminal_to_buffer(term, FALSE); } ! // The cursor may have been moved when resizing. vterm_state_get_cursorpos(state, &pos); position_cursor(wp, &pos); *************** *** 3546,3553 **** free_scrollback(term); redraw_buf_later(term->tl_buffer, NOT_VALID); ! /* The buffer is now like a normal buffer, it cannot be easily ! * abandoned when changed. */ set_string_option_direct((char_u *)"buftype", -1, (char_u *)"", OPT_FREE|OPT_LOCAL, 0); } --- 3545,3552 ---- free_scrollback(term); redraw_buf_later(term->tl_buffer, NOT_VALID); ! // The buffer is now like a normal buffer, it cannot be easily ! // abandoned when changed. set_string_option_direct((char_u *)"buftype", -1, (char_u *)"", OPT_FREE|OPT_LOCAL, 0); } *************** *** 3602,3609 **** fg = &term->tl_default_color.fg; bg = &term->tl_default_color.bg; ! /* Vterm uses a default black background. Set it to white when ! * 'background' is "light". */ if (*p_bg == 'l') { fgval = 0; --- 3601,3608 ---- fg = &term->tl_default_color.fg; bg = &term->tl_default_color.bg; ! // Vterm uses a default black background. Set it to white when ! // 'background' is "light". if (*p_bg == 'l') { fgval = 0; *************** *** 3618,3627 **** bg->red = bg->green = bg->blue = bgval; fg->ansi_index = bg->ansi_index = VTERM_ANSI_INDEX_DEFAULT; ! /* The "Terminal" highlight group overrules the defaults. */ id = syn_name2id((char_u *)"Terminal"); ! /* Use the actual color for the GUI and when 'termguicolors' is set. */ #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) if (0 # ifdef FEAT_GUI --- 3617,3626 ---- bg->red = bg->green = bg->blue = bgval; fg->ansi_index = bg->ansi_index = VTERM_ANSI_INDEX_DEFAULT; ! // The "Terminal" highlight group overrules the defaults. id = syn_name2id((char_u *)"Terminal"); ! // Use the actual color for the GUI and when 'termguicolors' is set. #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) if (0 # ifdef FEAT_GUI *************** *** 3630,3636 **** # ifdef FEAT_TERMGUICOLORS || p_tgc # ifdef FEAT_VTP ! /* Finally get INVALCOLOR on this execution path */ || (!p_tgc && t_colors >= 256) # endif # endif --- 3629,3635 ---- # ifdef FEAT_TERMGUICOLORS || p_tgc # ifdef FEAT_VTP ! // Finally get INVALCOLOR on this execution path || (!p_tgc && t_colors >= 256) # endif # endif *************** *** 3694,3700 **** int tmp; #endif ! /* In an MS-Windows console we know the normal colors. */ if (cterm_normal_fg_color > 0) { cterm_color2vterm(cterm_normal_fg_color - 1, fg); --- 3693,3699 ---- int tmp; #endif ! // In an MS-Windows console we know the normal colors. if (cterm_normal_fg_color > 0) { cterm_color2vterm(cterm_normal_fg_color - 1, fg); *************** *** 3826,3832 **** { if (wp->w_buffer->b_fnum == bufnr) { ! /* buffer is in a window already, go there */ goto_tabpage_win(tp, wp); return; } --- 3825,3831 ---- { if (wp->w_buffer->b_fnum == bufnr) { ! // buffer is in a window already, go there goto_tabpage_win(tp, wp); return; } *************** *** 3878,3884 **** ea.force_bin = FORCE_NOBIN; } ! /* open in new window, like ":split fname" */ if (ea.cmd == NULL) ea.cmd = (char_u *)"split"; ea.arg = fname; --- 3877,3883 ---- ea.force_bin = FORCE_NOBIN; } ! // open in new window, like ":split fname" if (ea.cmd == NULL) ea.cmd = (char_u *)"split"; ea.arg = fname; *************** *** 3951,3959 **** channel_T *channel = term->tl_job == NULL ? NULL : term->tl_job->jv_channel; ! /* We recognize only OSC 5 1 ; {command} */ if (cmdlen < 3 || STRNCMP(command, "51;", 3) != 0) ! return 0; /* not handled */ reader.js_buf = vim_strnsave((char_u *)command + 3, (int)(cmdlen - 3)); if (reader.js_buf == NULL) --- 3950,3958 ---- channel_T *channel = term->tl_job == NULL ? NULL : term->tl_job->jv_channel; ! // We recognize only OSC 5 1 ; {command} if (cmdlen < 3 || STRNCMP(command, "51;", 3) != 0) ! return 0; // not handled reader.js_buf = vim_strnsave((char_u *)command + 3, (int)(cmdlen - 3)); if (reader.js_buf == NULL) *************** *** 3972,3979 **** { char_u *cmd = tv_get_string(&item->li_tv); ! /* Make sure an invoked command doesn't delete the buffer (and the ! * terminal) under our fingers. */ ++term->tl_buffer->b_locked; item = item->li_next; --- 3971,3978 ---- { char_u *cmd = tv_get_string(&item->li_tv); ! // Make sure an invoked command doesn't delete the buffer (and the ! // terminal) under our fingers. ++term->tl_buffer->b_locked; item = item->li_next; *************** *** 4112,4118 **** } vterm_screen_set_callbacks(screen, &screen_callbacks, term); ! /* TODO: depends on 'encoding'. */ vterm_set_utf8(vterm, 1); init_default_colors(term); --- 4111,4117 ---- } vterm_screen_set_callbacks(screen, &screen_callbacks, term); ! // TODO: depends on 'encoding'. vterm_set_utf8(vterm, 1); init_default_colors(term); *************** *** 4127,4141 **** // the foreground color. vterm_state_set_bold_highbright(vterm_obtain_state(vterm), 1); ! /* Required to initialize most things. */ vterm_screen_reset(screen, 1 /* hard */); ! /* Allow using alternate screen. */ vterm_screen_enable_altscreen(screen, 1); ! /* For unix do not use a blinking cursor. In an xterm this causes the ! * cursor to blink if it's blinking in the xterm. ! * For Windows we respect the system wide setting. */ #ifdef MSWIN if (GetCaretBlinkTime() == INFINITE) value.boolean = 0; --- 4126,4140 ---- // the foreground color. vterm_state_set_bold_highbright(vterm_obtain_state(vterm), 1); ! // Required to initialize most things. vterm_screen_reset(screen, 1 /* hard */); ! // Allow using alternate screen. vterm_screen_enable_altscreen(screen, 1); ! // For unix do not use a blinking cursor. In an xterm this causes the ! // cursor to blink if it's blinking in the xterm. ! // For Windows we respect the system wide setting. #ifdef MSWIN if (GetCaretBlinkTime() == INFINITE) value.boolean = 0; *************** *** 4225,4231 **** { buf_T *buf; ! (void)tv_get_number(&argvars[0]); /* issue errmsg if type error */ ++emsg_off; buf = tv_get_buf(&argvars[0], FALSE); --emsg_off; --- 4224,4230 ---- { buf_T *buf; ! (void)tv_get_number(&argvars[0]); // issue errmsg if type error ++emsg_off; buf = tv_get_buf(&argvars[0], FALSE); --emsg_off; *************** *** 4364,4370 **** int c = cell.chars[i]; int pc = prev_cell.chars[i]; ! /* For the first character NUL is the same as space. */ if (i == 0) { c = (c == NUL) ? ' ' : c; --- 4363,4369 ---- int c = cell.chars[i]; int pc = prev_cell.chars[i]; ! // For the first character NUL is the same as space. if (i == 0) { c = (c == NUL) ? ' ' : c; *************** *** 4408,4416 **** } } ! /* When only the characters differ we don't write anything, the ! * following "|", "@" or NL will indicate using the same ! * attributes. */ if (cell.width != prev_cell.width || !same_attr) { if (cell.width == 2) --- 4407,4415 ---- } } ! // When only the characters differ we don't write anything, the ! // following "|", "@" or NL will indicate using the same ! // attributes. if (cell.width != prev_cell.width || !same_attr) { if (cell.width == 2) *************** *** 4512,4518 **** } else if (c == '\n') { ! /* End of a line: append it to the buffer. */ if (ga_text.ga_data == NULL) dump_is_corrupt(&ga_text); if (ga_grow(&term->tl_scrollback, 1) == OK) --- 4511,4517 ---- } else if (c == '\n') { ! // End of a line: append it to the buffer. if (ga_text.ga_data == NULL) dump_is_corrupt(&ga_text); if (ga_grow(&term->tl_scrollback, 1) == OK) *************** *** 4545,4556 **** if (c == '>') { if (cursor_pos->row != -1) ! dump_is_corrupt(&ga_text); /* duplicate cursor */ cursor_pos->row = term->tl_scrollback.ga_len - start_row; cursor_pos->col = ga_cell.ga_len; } ! /* normal character(s) followed by "+", "*", "|", "@" or NL */ c = fgetc(fd); if (c != EOF) ga_append(&ga_text, c); --- 4544,4555 ---- if (c == '>') { if (cursor_pos->row != -1) ! dump_is_corrupt(&ga_text); // duplicate cursor cursor_pos->row = term->tl_scrollback.ga_len - start_row; cursor_pos->col = ga_cell.ga_len; } ! // normal character(s) followed by "+", "*", "|", "@" or NL c = fgetc(fd); if (c != EOF) ga_append(&ga_text, c); *************** *** 4563,4569 **** ga_append(&ga_text, c); } ! /* save the character for repeating it */ vim_free(prev_char); if (ga_text.ga_data != NULL) prev_char = vim_strnsave(((char_u *)ga_text.ga_data) + prev_len, --- 4562,4568 ---- ga_append(&ga_text, c); } ! // save the character for repeating it vim_free(prev_char); if (ga_text.ga_data != NULL) prev_char = vim_strnsave(((char_u *)ga_text.ga_data) + prev_len, *************** *** 4571,4577 **** if (c == '@' || c == '|' || c == '>' || c == '\n') { ! /* use all attributes from previous cell */ } else if (c == '+' || c == '*') { --- 4570,4576 ---- if (c == '@' || c == '|' || c == '>' || c == '\n') { ! // use all attributes from previous cell } else if (c == '+' || c == '*') { *************** *** 4582,4593 **** c = fgetc(fd); if (c == '&') { ! /* use same attr as previous cell */ c = fgetc(fd); } else if (isdigit(c)) { ! /* get the decimal attribute */ attr = 0; while (isdigit(c)) { --- 4581,4592 ---- c = fgetc(fd); if (c == '&') { ! // use same attr as previous cell c = fgetc(fd); } else if (isdigit(c)) { ! // get the decimal attribute attr = 0; while (isdigit(c)) { *************** *** 4596,4607 **** } hl2vtermAttr(attr, &cell); ! /* is_bg == 0: fg, is_bg == 1: bg */ for (is_bg = 0; is_bg <= 1; ++is_bg) { if (c == '&') { ! /* use same color as previous cell */ c = fgetc(fd); } else if (c == '#') --- 4595,4606 ---- } hl2vtermAttr(attr, &cell); ! // is_bg == 0: fg, is_bg == 1: bg for (is_bg = 0; is_bg <= 1; ++is_bg) { if (c == '&') { ! // use same color as previous cell c = fgetc(fd); } else if (c == '#') *************** *** 4666,4672 **** { int count = 0; ! /* repeat previous character, get the count */ for (;;) { c = fgetc(fd); --- 4665,4671 ---- { int count = 0; ! // repeat previous character, get the count for (;;) { c = fgetc(fd); *************** *** 4691,4697 **** if (ga_text.ga_len > 0) { ! /* trailing characters after last NL */ dump_is_corrupt(&ga_text); ga_append(&ga_text, NUL); ml_append(curbuf->b_ml.ml_line_count, ga_text.ga_data, --- 4690,4696 ---- if (ga_text.ga_len > 0) { ! // trailing characters after last NL dump_is_corrupt(&ga_text); ga_append(&ga_text, NUL); ml_append(curbuf->b_ml.ml_line_count, ga_text.ga_data, *************** *** 4726,4741 **** fname_size = vim_strsize(fname); if (fname_size < width - 8) { ! /* enough room, don't use the full window width */ width = MAX(text_width, fname_size + 8); } else if (fname_size > width - 8) { ! /* full name doesn't fit, use only the tail */ p = gettail(fname); fname_size = vim_strsize(p); } ! /* skip characters until the name fits */ while (fname_size > width - 8) { p += (*mb_ptr2len)(p); --- 4725,4740 ---- fname_size = vim_strsize(fname); if (fname_size < width - 8) { ! // enough room, don't use the full window width width = MAX(text_width, fname_size + 8); } else if (fname_size > width - 8) { ! // full name doesn't fit, use only the tail p = gettail(fname); fname_size = vim_strsize(p); } ! // skip characters until the name fits while (fname_size > width - 8) { p += (*mb_ptr2len)(p); *************** *** 4773,4779 **** FILE *fd2 = NULL; char_u *textline = NULL; ! /* First open the files. If this fails bail out. */ fname1 = tv_get_string_buf_chk(&argvars[0], buf1); if (do_diff) fname2 = tv_get_string_buf_chk(&argvars[1], buf2); --- 4772,4778 ---- FILE *fd2 = NULL; char_u *textline = NULL; ! // First open the files. If this fails bail out. fname1 = tv_get_string_buf_chk(&argvars[0], buf1); if (do_diff) fname2 = tv_get_string_buf_chk(&argvars[1], buf2); *************** *** 4854,4873 **** rettv->vval.v_number = buf->b_fnum; ! /* read the files, fill the buffer with the diff */ width = read_dump_file(fd1, &cursor_pos1); ! /* position the cursor */ if (cursor_pos1.row >= 0) { curwin->w_cursor.lnum = cursor_pos1.row + 1; coladvance(cursor_pos1.col); } ! /* Delete the empty line that was in the empty buffer. */ ml_delete(1, FALSE); ! /* For term_dumpload() we are done here. */ if (!do_diff) goto theend; --- 4853,4872 ---- rettv->vval.v_number = buf->b_fnum; ! // read the files, fill the buffer with the diff width = read_dump_file(fd1, &cursor_pos1); ! // position the cursor if (cursor_pos1.row >= 0) { curwin->w_cursor.lnum = cursor_pos1.row + 1; coladvance(cursor_pos1.col); } ! // Delete the empty line that was in the empty buffer. ml_delete(1, FALSE); ! // For term_dumpload() we are done here. if (!do_diff) goto theend; *************** *** 4904,4910 **** { if (lnum + bot_lnum > curbuf->b_ml.ml_line_count) { ! /* bottom part has fewer rows, fill with "-" */ for (i = 0; i < width; ++i) textline[i] = '-'; } --- 4903,4909 ---- { if (lnum + bot_lnum > curbuf->b_ml.ml_line_count) { ! // bottom part has fewer rows, fill with "-" for (i = 0; i < width; ++i) textline[i] = '-'; } *************** *** 4920,4926 **** cellattr_T *cellattr2 = (sb_line + lnum + bot_lnum - 1) ->sb_cells; ! /* Make a copy, getting the second line will invalidate it. */ line1 = vim_strsave(ml_get(lnum)); if (line1 == NULL) break; --- 4919,4925 ---- cellattr_T *cellattr2 = (sb_line + lnum + bot_lnum - 1) ->sb_cells; ! // Make a copy, getting the second line will invalidate it. line1 = vim_strsave(ml_get(lnum)); if (line1 == NULL) break; *************** *** 4935,4953 **** textline[col] = ' '; if (len1 != len2 || STRNCMP(p1, p2, len1) != 0) ! /* text differs */ textline[col] = 'X'; else if (lnum == cursor_pos1.row + 1 && col == cursor_pos1.col && (cursor_pos1.row != cursor_pos2.row || cursor_pos1.col != cursor_pos2.col)) ! /* cursor in first but not in second */ textline[col] = '>'; else if (lnum == cursor_pos2.row + 1 && col == cursor_pos2.col && (cursor_pos1.row != cursor_pos2.row || cursor_pos1.col != cursor_pos2.col)) ! /* cursor in second but not in first */ textline[col] = '<'; else if (cellattr1 != NULL && cellattr2 != NULL) { --- 4934,4952 ---- textline[col] = ' '; if (len1 != len2 || STRNCMP(p1, p2, len1) != 0) ! // text differs textline[col] = 'X'; else if (lnum == cursor_pos1.row + 1 && col == cursor_pos1.col && (cursor_pos1.row != cursor_pos2.row || cursor_pos1.col != cursor_pos2.col)) ! // cursor in first but not in second textline[col] = '>'; else if (lnum == cursor_pos2.row + 1 && col == cursor_pos2.col && (cursor_pos1.row != cursor_pos2.row || cursor_pos1.col != cursor_pos2.col)) ! // cursor in second but not in first textline[col] = '<'; else if (cellattr1 != NULL && cellattr2 != NULL) { *************** *** 4966,4972 **** } p1 += len1; p2 += len2; ! /* TODO: handle different width */ } while (col < width) --- 4965,4971 ---- } p1 += len1; p2 += len2; ! // TODO: handle different width } while (col < width) *************** *** 4996,5002 **** while (lnum + bot_lnum <= curbuf->b_ml.ml_line_count) { ! /* bottom part has more rows, fill with "+" */ for (i = 0; i < width; ++i) textline[i] = '+'; if (add_empty_scrollback(term, &term->tl_default_color, --- 4995,5001 ---- while (lnum + bot_lnum <= curbuf->b_ml.ml_line_count) { ! // bottom part has more rows, fill with "+" for (i = 0; i < width; ++i) textline[i] = '+'; if (add_empty_scrollback(term, &term->tl_default_color, *************** *** 5008,5014 **** term->tl_cols = width; ! /* looks better without wrapping */ curwin->w_p_wrap = 0; } --- 5007,5013 ---- term->tl_cols = width; ! // looks better without wrapping curwin->w_p_wrap = 0; } *************** *** 5089,5095 **** if (top_rows == bot_rows) { ! /* rows counts are equal, can swap cell properties */ for (lnum = 0; lnum < top_rows; ++lnum) { sb_line_T temp; --- 5088,5094 ---- if (top_rows == bot_rows) { ! // rows counts are equal, can swap cell properties for (lnum = 0; lnum < top_rows; ++lnum) { sb_line_T temp; *************** *** 5104,5110 **** size_t size = sizeof(sb_line_T) * term->tl_scrollback.ga_len; sb_line_T *temp = alloc(size); ! /* need to copy cell properties into temp memory */ if (temp != NULL) { mch_memmove(temp, term->tl_scrollback.ga_data, size); --- 5103,5109 ---- size_t size = sizeof(sb_line_T) * term->tl_scrollback.ga_len; sb_line_T *temp = alloc(size); ! // need to copy cell properties into temp memory if (temp != NULL) { mch_memmove(temp, term->tl_scrollback.ga_data, size); *************** *** 5280,5286 **** { linenr_T lnum = row + term->tl_scrollback_scrolled + 1; ! /* vterm is finished, get the text from the buffer */ if (lnum > 0 && lnum <= buf->b_ml.ml_line_count) rettv->vval.v_string = vim_strsave(ml_get_buf(buf, lnum, FALSE)); } --- 5279,5285 ---- { linenr_T lnum = row + term->tl_scrollback_scrolled + 1; ! // vterm is finished, get the text from the buffer if (lnum > 0 && lnum <= buf->b_ml.ml_line_count) rettv->vval.v_string = vim_strsave(ml_get_buf(buf, lnum, FALSE)); } *************** *** 5362,5370 **** cols = tv_get_number(&argvars[2]); cols = cols <= 0 ? term->tl_cols : cols; vterm_set_size(term->tl_vterm, rows, cols); ! /* handle_resize() will resize the windows */ ! /* Get and remember the size we ended up with. Update the pty. */ vterm_get_size(term->tl_vterm, &term->tl_rows, &term->tl_cols); term_report_winsize(term, term->tl_rows, term->tl_cols); } --- 5361,5369 ---- cols = tv_get_number(&argvars[2]); cols = cols <= 0 ? term->tl_cols : cols; vterm_set_size(term->tl_vterm, rows, cols); ! // handle_resize() will resize the windows ! // Get and remember the size we ended up with. Update the pty. vterm_get_size(term->tl_vterm, &term->tl_rows, &term->tl_cols); term_report_winsize(term, term->tl_rows, term->tl_cols); } *************** *** 5520,5526 **** cellattr_T *cellattr; int len; ! /* vterm has finished, get the cell from scrollback */ if (pos.col >= line->sb_cols) break; cellattr = line->sb_cells + pos.col; --- 5519,5525 ---- cellattr_T *cellattr; int len; ! // vterm has finished, get the cell from scrollback if (pos.col >= line->sb_cols) break; cellattr = line->sb_cells + pos.col; *************** *** 5783,5798 **** return; } if (buf->b_term->tl_job->jv_channel == NULL) ! /* channel is closed, nothing to do */ return; ! /* Get the job status, this will detect a job that finished. */ if (!buf->b_term->tl_job->jv_channel->ch_keep_open && STRCMP(job_status(buf->b_term->tl_job), "dead") == 0) { ! /* The job is dead, keep reading channel I/O until the channel is ! * closed. buf->b_term may become NULL if the terminal was closed while ! * waiting. */ ch_log(NULL, "term_wait(): waiting for channel to close"); while (buf->b_term != NULL && !buf->b_term->tl_channel_closed) { --- 5782,5797 ---- return; } if (buf->b_term->tl_job->jv_channel == NULL) ! // channel is closed, nothing to do return; ! // Get the job status, this will detect a job that finished. if (!buf->b_term->tl_job->jv_channel->ch_keep_open && STRCMP(job_status(buf->b_term->tl_job), "dead") == 0) { ! // The job is dead, keep reading channel I/O until the channel is ! // closed. buf->b_term may become NULL if the terminal was closed while ! // waiting. ch_log(NULL, "term_wait(): waiting for channel to close"); while (buf->b_term != NULL && !buf->b_term->tl_channel_closed) { *************** *** 5800,5807 **** ui_delay(10L, FALSE); if (!buf_valid(buf)) ! /* If the terminal is closed when the channel is closed the ! * buffer disappears. */ break; } --- 5799,5806 ---- ui_delay(10L, FALSE); if (!buf_valid(buf)) ! // If the terminal is closed when the channel is closed the ! // buffer disappears. break; } *************** *** 5813,5825 **** term_flush_messages(); ! /* Wait for some time for any channel I/O. */ if (argvars[1].v_type != VAR_UNKNOWN) wait = tv_get_number(&argvars[1]); ui_delay(wait, TRUE); ! /* Flushing messages on channels is hopefully sufficient. ! * TODO: is there a better way? */ term_flush_messages(); } } --- 5812,5824 ---- term_flush_messages(); ! // Wait for some time for any channel I/O. if (argvars[1].v_type != VAR_UNKNOWN) wait = tv_get_number(&argvars[1]); ui_delay(wait, TRUE); ! // Flushing messages on channels is hopefully sufficient. ! // TODO: is there a better way? term_flush_messages(); } } *************** *** 5844,5850 **** } # ifdef MSWIN else ! /* Default: CTRL-D */ channel_send(ch, PART_IN, (char_u *)"\004\r", 2, NULL); # endif } --- 5843,5849 ---- } # ifdef MSWIN else ! // Default: CTRL-D channel_send(ch, PART_IN, (char_u *)"\004\r", 2, NULL); # endif } *************** *** 5860,5868 **** # if defined(MSWIN) || defined(PROTO) ! /************************************** ! * 2. MS-Windows implementation. ! */ #ifdef PROTO typedef int COORD; typedef int DWORD; --- 5859,5866 ---- # if defined(MSWIN) || defined(PROTO) ! /////////////////////////////////////// ! // 2. MS-Windows implementation. #ifdef PROTO typedef int COORD; typedef int DWORD; *************** *** 5987,5994 **** if (cmd_wchar != NULL) { ! /* Request by CreateProcessW */ ! breq = wcslen(cmd_wchar) + 1 + 1; /* Addition of NUL by API */ cmd_wchar_copy = ALLOC_MULT(WCHAR, breq); wcsncpy(cmd_wchar_copy, cmd_wchar, breq - 1); } --- 5985,5992 ---- if (cmd_wchar != NULL) { ! // Request by CreateProcessW ! breq = wcslen(cmd_wchar) + 1 + 1; // Addition of NUL by API cmd_wchar_copy = ALLOC_MULT(WCHAR, breq); wcsncpy(cmd_wchar_copy, cmd_wchar, breq - 1); } *************** *** 6016,6022 **** term->tl_siex.StartupInfo.cb = sizeof(term->tl_siex); ! /* Set up pipe inheritance safely: Vista or later. */ pInitializeProcThreadAttributeList(NULL, 1, 0, &breq); term->tl_siex.lpAttributeList = alloc(breq); if (!term->tl_siex.lpAttributeList) --- 6014,6020 ---- term->tl_siex.StartupInfo.cb = sizeof(term->tl_siex); ! // Set up pipe inheritance safely: Vista or later. pInitializeProcThreadAttributeList(NULL, 1, 0, &breq); term->tl_siex.lpAttributeList = alloc(breq); if (!term->tl_siex.lpAttributeList) *************** *** 6069,6078 **** (sock_T)o_ours, (sock_T)o_ours); ! /* Write lines with CR instead of NL. */ channel->ch_write_text_mode = TRUE; ! /* Use to explicitly delete anonymous pipe handle. */ channel->ch_anonymous_pipe = TRUE; jo = CreateJobObject(NULL, NULL); --- 6067,6076 ---- (sock_T)o_ours, (sock_T)o_ours); ! // Write lines with CR instead of NL. channel->ch_write_text_mode = TRUE; ! // Use to explicitly delete anonymous pipe handle. channel->ch_anonymous_pipe = TRUE; jo = CreateJobObject(NULL, NULL); *************** *** 6081,6087 **** if (!AssignProcessToJobObject(jo, proc_info.hProcess)) { ! /* Failed, switch the way to terminate process with TerminateProcess. */ CloseHandle(jo); jo = NULL; } --- 6079,6085 ---- if (!AssignProcessToJobObject(jo, proc_info.hProcess)) { ! // Failed, switch the way to terminate process with TerminateProcess. CloseHandle(jo); jo = NULL; } *************** *** 6115,6123 **** ++job->jv_refcount; term->tl_job = job; ! /* Redirecting stdout and stderr doesn't work at the job level. Instead ! * open the file here and handle it in. opt->jo_io was changed in ! * setup_job_options(), use the original flags here. */ if (orig_opt->jo_io[PART_OUT] == JIO_FILE) { char_u *fname = opt->jo_io_name[PART_OUT]; --- 6113,6121 ---- ++job->jv_refcount; term->tl_job = job; ! // Redirecting stdout and stderr doesn't work at the job level. Instead ! // open the file here and handle it in. opt->jo_io was changed in ! // setup_job_options(), use the original flags here. if (orig_opt->jo_io[PART_OUT] == JIO_FILE) { char_u *fname = opt->jo_io_name[PART_OUT]; *************** *** 6256,6266 **** {NULL, NULL} }; ! /* No need to initialize twice. */ if (hWinPtyDLL) return OK; ! /* Load winpty.dll, prefer using the 'winptydll' option, fall back to just ! * winpty.dll. */ if (*p_winptydll != NUL) hWinPtyDLL = vimLoadLib((char *)p_winptydll); if (!hWinPtyDLL) --- 6254,6264 ---- {NULL, NULL} }; ! // No need to initialize twice. if (hWinPtyDLL) return OK; ! // Load winpty.dll, prefer using the 'winptydll' option, fall back to just ! // winpty.dll. if (*p_winptydll != NUL) hWinPtyDLL = vimLoadLib((char *)p_winptydll); if (!hWinPtyDLL) *************** *** 6405,6411 **** GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)); ! /* Write lines with CR instead of NL. */ channel->ch_write_text_mode = TRUE; jo = CreateJobObject(NULL, NULL); --- 6403,6409 ---- GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)); ! // Write lines with CR instead of NL. channel->ch_write_text_mode = TRUE; jo = CreateJobObject(NULL, NULL); *************** *** 6414,6420 **** if (!AssignProcessToJobObject(jo, child_process_handle)) { ! /* Failed, switch the way to terminate process with TerminateProcess. */ CloseHandle(jo); jo = NULL; } --- 6412,6418 ---- if (!AssignProcessToJobObject(jo, child_process_handle)) { ! // Failed, switch the way to terminate process with TerminateProcess. CloseHandle(jo); jo = NULL; } *************** *** 6450,6458 **** ++job->jv_refcount; term->tl_job = job; ! /* Redirecting stdout and stderr doesn't work at the job level. Instead ! * open the file here and handle it in. opt->jo_io was changed in ! * setup_job_options(), use the original flags here. */ if (orig_opt->jo_io[PART_OUT] == JIO_FILE) { char_u *fname = opt->jo_io_name[PART_OUT]; --- 6448,6456 ---- ++job->jv_refcount; term->tl_job = job; ! // Redirecting stdout and stderr doesn't work at the job level. Instead ! // open the file here and handle it in. opt->jo_io was changed in ! // setup_job_options(), use the original flags here. if (orig_opt->jo_io[PART_OUT] == JIO_FILE) { char_u *fname = opt->jo_io_name[PART_OUT]; *************** *** 6597,6603 **** goto failed; ++term->tl_job->jv_refcount; ! /* behave like the job is already finished */ term->tl_job->jv_status = JOB_FINISHED; channel = add_channel(); --- 6595,6601 ---- goto failed; ++term->tl_job->jv_refcount; ! // behave like the job is already finished term->tl_job->jv_status = JOB_FINISHED; channel = add_channel(); *************** *** 6663,6671 **** # else ! /************************************** ! * 3. Unix-like implementation. ! */ /* * Create a new terminal of "rows" by "cols" cells. --- 6661,6668 ---- # else ! /////////////////////////////////////// ! // 3. Unix-like implementation. /* * Create a new terminal of "rows" by "cols" cells. *************** *** 6694,6700 **** init_vterm_ansi_colors(term->tl_vterm); #endif ! /* This may change a string in "argvar". */ term->tl_job = job_start(argvar, argv, opt, TRUE); if (term->tl_job != NULL) ++term->tl_job->jv_refcount; --- 6691,6697 ---- init_vterm_ansi_colors(term->tl_vterm); #endif ! // This may change a string in "argvar". term->tl_job = job_start(argvar, argv, opt, TRUE); if (term->tl_job != NULL) ++term->tl_job->jv_refcount; *************** *** 6715,6721 **** return FAIL; ++term->tl_job->jv_refcount; ! /* behave like the job is already finished */ term->tl_job->jv_status = JOB_FINISHED; return mch_create_pty_channel(term->tl_job, opt); --- 6712,6718 ---- return FAIL; ++term->tl_job->jv_refcount; ! // behave like the job is already finished term->tl_job->jv_status = JOB_FINISHED; return mch_create_pty_channel(term->tl_job, opt); *************** *** 6738,6744 **** static void term_report_winsize(term_T *term, int rows, int cols) { ! /* Use an ioctl() to report the new window size to the job. */ if (term->tl_job != NULL && term->tl_job->jv_channel != NULL) { int fd = -1; --- 6735,6741 ---- static void term_report_winsize(term_T *term, int rows, int cols) { ! // Use an ioctl() to report the new window size to the job. if (term->tl_job != NULL && term->tl_job->jv_channel != NULL) { int fd = -1; *************** *** 6757,6760 **** # endif ! #endif /* FEAT_TERMINAL */ --- 6754,6757 ---- # endif ! #endif // FEAT_TERMINAL *** ../vim-8.1.2394/src/termlib.c 2017-10-28 20:52:48.000000000 +0200 --- src/termlib.c 2019-12-05 21:32:07.179092746 +0100 *************** *** 5,14 **** * inclusion of this notice. */ ! /* Modified by Bram Moolenaar for use with VIM - Vi Improved. */ ! /* A few bugs removed by Olaf 'Rhialto' Seibert. */ ! /* TERMLIB: Terminal independent database. */ #include "vim.h" #include "termlib.pro" --- 5,14 ---- * inclusion of this notice. */ ! // Modified by Bram Moolenaar for use with VIM - Vi Improved. ! // A few bugs removed by Olaf 'Rhialto' Seibert. ! // TERMLIB: Terminal independent database. #include "vim.h" #include "termlib.pro" *************** *** 27,36 **** * Global variables for termlib */ ! char *tent; /* Pointer to terminal entry, set by tgetent */ ! char PC = 0; /* Pad character, default NULL */ ! char *UP = 0, *BC = 0; /* Pointers to UP and BC strings from database */ ! short ospeed; /* Baud rate (1-16, 1=300, 16=19200), as in stty */ /* * Module: tgetent --- 27,36 ---- * Global variables for termlib */ ! char *tent; // Pointer to terminal entry, set by tgetent ! char PC = 0; // Pad character, default NULL ! char *UP = 0, *BC = 0; // Pointers to UP and BC strings from database ! short ospeed; // Baud rate (1-16, 1=300, 16=19200), as in stty /* * Module: tgetent *************** *** 67,78 **** int tgetent( ! char *tbuf, /* Buffer to hold termcap entry, TBUFSZ bytes max */ ! char *term) /* Name of terminal */ { ! char tcbuf[32]; /* Temp buffer to handle */ ! char *tcptr = tcbuf; /* extended entries */ ! char *tcap = TERMCAPFILE; /* Default termcap file */ char *tmp; FILE *termcap; int retval = 0; --- 67,78 ---- int tgetent( ! char *tbuf, // Buffer to hold termcap entry, TBUFSZ bytes max ! char *term) // Name of terminal { ! char tcbuf[32]; // Temp buffer to handle ! char *tcptr = tcbuf; // extended entries ! char *tcap = TERMCAPFILE; // Default termcap file char *tmp; FILE *termcap; int retval = 0; *************** *** 80,107 **** if ((tmp = (char *)mch_getenv((char_u *)"TERMCAP")) != NULL) { ! if (*tmp == '/') /* TERMCAP = name of termcap file */ { tcap = tmp ; #if defined(AMIGA) ! /* Convert /usr/share/lib/termcap to usr:share/lib/termcap */ tcap++; tmp = strchr(tcap, '/'); if (tmp) *tmp = ':'; #endif } ! else /* TERMCAP = termcap entry itself */ { int tlen = strlen(term); ! while (*tmp && *tmp != ':') /* Check if TERM matches */ { char *nexttmp; while (*tmp == '|') tmp++; ! nexttmp = _find(tmp, ":|"); /* Rhialto */ if (tmp+tlen == nexttmp && _match(tmp, term) == tlen) { strcpy(tbuf, tmp); --- 80,107 ---- if ((tmp = (char *)mch_getenv((char_u *)"TERMCAP")) != NULL) { ! if (*tmp == '/') // TERMCAP = name of termcap file { tcap = tmp ; #if defined(AMIGA) ! // Convert /usr/share/lib/termcap to usr:share/lib/termcap tcap++; tmp = strchr(tcap, '/'); if (tmp) *tmp = ':'; #endif } ! else // TERMCAP = termcap entry itself { int tlen = strlen(term); ! while (*tmp && *tmp != ':') // Check if TERM matches { char *nexttmp; while (*tmp == '|') tmp++; ! nexttmp = _find(tmp, ":|"); // Rhialto if (tmp+tlen == nexttmp && _match(tmp, term) == tlen) { strcpy(tbuf, tmp); *************** *** 122,129 **** len = 0; while (getent(tbuf + len, term, termcap, TBUFSZ - len)) { ! tcptr = tcbuf; /* Rhialto */ ! if ((term = tgetstr("tc", &tcptr))) /* extended entry */ { rewind(termcap); len = strlen(tbuf); --- 122,129 ---- len = 0; while (getent(tbuf + len, term, termcap, TBUFSZ - len)) { ! tcptr = tcbuf; // Rhialto ! if ((term = tgetstr("tc", &tcptr))) // extended entry { rewind(termcap); len = strlen(tbuf); *************** *** 131,137 **** else { retval = 1; ! tent = tbuf; /* reset it back to the beginning */ break; } } --- 131,137 ---- else { retval = 1; ! tent = tbuf; // reset it back to the beginning break; } } *************** *** 145,167 **** char *tptr; int tlen = strlen(term); ! while (nextent(tbuf, termcap, buflen)) /* For each possible entry */ { tptr = tbuf; ! while (*tptr && *tptr != ':') /* : terminates name field */ { char *nexttptr; ! while (*tptr == '|') /* | separates names */ tptr++; ! nexttptr = _find(tptr, ":|"); /* Rhialto */ if (tptr + tlen == nexttptr && ! _match(tptr, term) == tlen) /* FOUND! */ { tent = tbuf; return 1; } ! else /* Look for next name */ tptr = nexttptr; } } --- 145,167 ---- char *tptr; int tlen = strlen(term); ! while (nextent(tbuf, termcap, buflen)) // For each possible entry { tptr = tbuf; ! while (*tptr && *tptr != ':') // : terminates name field { char *nexttptr; ! while (*tptr == '|') // | separates names tptr++; ! nexttptr = _find(tptr, ":|"); // Rhialto if (tptr + tlen == nexttptr && ! _match(tptr, term) == tlen) // FOUND! { tent = tbuf; return 1; } ! else // Look for next name tptr = nexttptr; } } *************** *** 174,206 **** static int nextent(char *tbuf, FILE *termcap, int buflen) { ! char *lbuf = tbuf; /* lbuf=line buffer */ ! /* read lines straight into buffer */ ! while (lbuf < tbuf+buflen && /* There's room and */ ! fgets(lbuf, (int)(tbuf+buflen-lbuf), termcap)) /* another line */ { int llen = strlen(lbuf); ! if (*lbuf == '#') /* eat comments */ continue; ! if (lbuf[-1] == ':' && /* and whitespace */ lbuf[0] == '\t' && lbuf[1] == ':') { STRMOVE(lbuf, lbuf + 2); llen -= 2; } ! if (lbuf[llen-2] == '\\') /* and continuations */ lbuf += llen-2; else { ! lbuf[llen-1]=0; /* no continuation, return */ return 1; } } ! return 0; /* ran into end of file */ } /* --- 174,206 ---- static int nextent(char *tbuf, FILE *termcap, int buflen) { ! char *lbuf = tbuf; // lbuf=line buffer ! // read lines straight into buffer ! while (lbuf < tbuf+buflen && // There's room and ! fgets(lbuf, (int)(tbuf+buflen-lbuf), termcap)) // another line { int llen = strlen(lbuf); ! if (*lbuf == '#') // eat comments continue; ! if (lbuf[-1] == ':' && // and whitespace lbuf[0] == '\t' && lbuf[1] == ':') { STRMOVE(lbuf, lbuf + 2); llen -= 2; } ! if (lbuf[llen-2] == '\\') // and continuations lbuf += llen-2; else { ! lbuf[llen-1]=0; // no continuation, return return 1; } } ! return 0; // ran into end of file } /* *************** *** 280,323 **** int i; do { ! tmp = _find(tmp, ":"); /* For each field */ ! while (*tmp == ':') /* skip empty fields */ tmp++; if (!*tmp) break; if (_match(id, tmp) == len) { ! tmp += len; /* find '=' '@' or '#' */ ! if (*tmp == '@') /* :xx@: entry for tc */ ! return 0; /* deleted entry */ hold= *buf; ! while (*++tmp && *tmp != ':') { /* not at end of field */ switch(*tmp) { ! case '\\': /* Expand escapes here */ switch(*++tmp) { ! case 0: /* ignore backslashes */ ! tmp--; /* at end of entry */ ! break; /* shouldn't happen */ case 'e': ! case 'E': /* ESC */ *(*buf)++ = ESC; break; ! case 'n': /* \n */ *(*buf)++ = '\n'; break; ! case 'r': /* \r */ *(*buf)++ = '\r'; break; ! case 't': /* \t */ *(*buf)++ = '\t'; break; ! case 'b': /* \b */ *(*buf)++ = '\b'; break; ! case 'f': /* \f */ *(*buf)++ = '\f'; break; ! case '0': /* \nnn */ case '1': case '2': case '3': --- 280,323 ---- int i; do { ! tmp = _find(tmp, ":"); // For each field ! while (*tmp == ':') // skip empty fields tmp++; if (!*tmp) break; if (_match(id, tmp) == len) { ! tmp += len; // find '=' '@' or '#' ! if (*tmp == '@') // :xx@: entry for tc ! return 0; // deleted entry hold= *buf; ! while (*++tmp && *tmp != ':') { // not at end of field switch(*tmp) { ! case '\\': // Expand escapes here switch(*++tmp) { ! case 0: // ignore backslashes ! tmp--; // at end of entry ! break; // shouldn't happen case 'e': ! case 'E': // ESC *(*buf)++ = ESC; break; ! case 'n': // \n *(*buf)++ = '\n'; break; ! case 'r': // \r *(*buf)++ = '\r'; break; ! case 't': // \t *(*buf)++ = '\t'; break; ! case 'b': // \b *(*buf)++ = '\b'; break; ! case 'f': // \f *(*buf)++ = '\f'; break; ! case '0': // \nnn case '1': case '2': case '3': *************** *** 328,344 **** case '8': case '9': **buf = 0; ! /* get up to three digits */ for (i = 0; i < 3 && VIM_ISDIGIT(*tmp); ++i) **buf = **buf * 8 + *tmp++ - '0'; (*buf)++; tmp--; break; ! default: /* \x, for all other x */ *(*buf)++= *tmp; } break; ! case '^': /* control characters */ ++tmp; *(*buf)++ = Ctrl_chr(*tmp); break; --- 328,344 ---- case '8': case '9': **buf = 0; ! // get up to three digits for (i = 0; i < 3 && VIM_ISDIGIT(*tmp); ++i) **buf = **buf * 8 + *tmp++ - '0'; (*buf)++; tmp--; break; ! default: // \x, for all other x *(*buf)++= *tmp; } break; ! case '^': // control characters ++tmp; *(*buf)++ = Ctrl_chr(*tmp); break; *************** *** 382,477 **** char * tgoto( ! char *cm, /* cm string, from termcap */ ! int col, /* column, x position */ ! int line) /* line, y position */ { ! char gx, gy, /* x, y */ ! *ptr, /* pointer in 'cm' */ ! reverse = 0, /* reverse flag */ ! *bufp, /* pointer in returned string */ ! addup = 0, /* add upline */ ! addbak = 0, /* add backup */ c; static char buffer[32]; if (!cm) ! return "OOPS"; /* Kludge, but standard */ bufp = buffer; ptr = cm; while (*ptr) { ! if ((c = *ptr++) != '%') { /* normal char */ *bufp++ = c; ! } else { /* % escape */ switch(c = *ptr++) { ! case 'd': /* decimal */ bufp = _addfmt(bufp, "%d", line); line = col; break; ! case '2': /* 2 digit decimal */ bufp = _addfmt(bufp, "%02d", line); line = col; break; ! case '3': /* 3 digit decimal */ bufp = _addfmt(bufp, "%03d", line); line = col; break; ! case '>': /* %>xy: if >x, add y */ gx = *ptr++; gy = *ptr++; if (col>gx) col += gy; if (line>gx) line += gy; break; ! case '+': /* %+c: add c */ line += *ptr++; ! case '.': /* print x/y */ ! if (line == '\t' || /* these are */ ! line == '\n' || /* chars that */ ! line == '\004' || /* UNIX hates */ line == '\0') { ! line++; /* so go to next pos */ if (reverse == (line == col)) ! addup=1; /* and mark UP */ else ! addbak=1; /* or BC */ } *bufp++=line; line = col; break; ! case 'r': /* r: reverse */ gx = line; line = col; col = gx; reverse = 1; break; ! case 'i': /* increment (1-origin screen) */ col++; line++; break; ! case '%': /* %%=% literally */ *bufp++='%'; break; ! case 'n': /* magic DM2500 code */ line ^= 0140; col ^= 0140; break; ! case 'B': /* bcd encoding */ line = line/10<<4+line%10; col = col/10<<4+col%10; break; ! case 'D': /* magic Delta Data code */ line = line-2*(line&15); col = col-2*(col&15); break; ! default: /* Unknown escape */ return "OOPS"; } } } ! if (addup) /* add upline */ if (UP) { ptr=UP; while (VIM_ISDIGIT(*ptr) || *ptr == '.') --- 382,477 ---- char * tgoto( ! char *cm, // cm string, from termcap ! int col, // column, x position ! int line) // line, y position { ! char gx, gy, // x, y ! *ptr, // pointer in 'cm' ! reverse = 0, // reverse flag ! *bufp, // pointer in returned string ! addup = 0, // add upline ! addbak = 0, // add backup c; static char buffer[32]; if (!cm) ! return "OOPS"; // Kludge, but standard bufp = buffer; ptr = cm; while (*ptr) { ! if ((c = *ptr++) != '%') { // normal char *bufp++ = c; ! } else { // % escape switch(c = *ptr++) { ! case 'd': // decimal bufp = _addfmt(bufp, "%d", line); line = col; break; ! case '2': // 2 digit decimal bufp = _addfmt(bufp, "%02d", line); line = col; break; ! case '3': // 3 digit decimal bufp = _addfmt(bufp, "%03d", line); line = col; break; ! case '>': // %>xy: if >x, add y gx = *ptr++; gy = *ptr++; if (col>gx) col += gy; if (line>gx) line += gy; break; ! case '+': // %+c: add c line += *ptr++; ! case '.': // print x/y ! if (line == '\t' || // these are ! line == '\n' || // chars that ! line == '\004' || // UNIX hates line == '\0') { ! line++; // so go to next pos if (reverse == (line == col)) ! addup=1; // and mark UP else ! addbak=1; // or BC } *bufp++=line; line = col; break; ! case 'r': // r: reverse gx = line; line = col; col = gx; reverse = 1; break; ! case 'i': // increment (1-origin screen) col++; line++; break; ! case '%': // %%=% literally *bufp++='%'; break; ! case 'n': // magic DM2500 code line ^= 0140; col ^= 0140; break; ! case 'B': // bcd encoding line = line/10<<4+line%10; col = col/10<<4+col%10; break; ! case 'D': // magic Delta Data code line = line-2*(line&15); col = col-2*(col&15); break; ! default: // Unknown escape return "OOPS"; } } } ! if (addup) // add upline if (UP) { ptr=UP; while (VIM_ISDIGIT(*ptr) || *ptr == '.') *************** *** 482,488 **** *bufp++ = *ptr++; } ! if (addbak) /* add backspace */ if (BC) { ptr=BC; while (VIM_ISDIGIT(*ptr) || *ptr == '.') --- 482,488 ---- *bufp++ = *ptr++; } ! if (addbak) // add backspace if (BC) { ptr=BC; while (VIM_ISDIGIT(*ptr) || *ptr == '.') *************** *** 528,539 **** int tputs( ! char *cp, /* string to print */ ! int affcnt, /* Number of lines affected */ ! void (*outc)(unsigned int)) /* routine to output 1 character */ { ! long frac, /* 10^(#digits after decimal point) */ ! counter, /* digits */ atol(const char *); if (VIM_ISDIGIT(*cp)) { --- 528,539 ---- int tputs( ! char *cp, // string to print ! int affcnt, // Number of lines affected ! void (*outc)(unsigned int)) // routine to output 1 character { ! long frac, // 10^(#digits after decimal point) ! counter, // digits atol(const char *); if (VIM_ISDIGIT(*cp)) { *************** *** 546,565 **** counter = counter * 10L + (long)(*cp++ - '0'); frac = frac * 10; } ! if (*cp!='*') { /* multiply by affected lines */ if (affcnt>1) affcnt = 1; } else cp++; ! /* Calculate number of characters for padding counter/frac ms delay */ if (ospeed) counter = (counter * _bauds[ospeed] * (long)affcnt) / frac; ! while (*cp) /* output string */ (*outc)(*cp++); if (ospeed) ! while (counter--) /* followed by pad characters */ (*outc)(PC); } else --- 546,565 ---- counter = counter * 10L + (long)(*cp++ - '0'); frac = frac * 10; } ! if (*cp!='*') { // multiply by affected lines if (affcnt>1) affcnt = 1; } else cp++; ! // Calculate number of characters for padding counter/frac ms delay if (ospeed) counter = (counter * _bauds[ospeed] * (long)affcnt) / frac; ! while (*cp) // output string (*outc)(*cp++); if (ospeed) ! while (counter--) // followed by pad characters (*outc)(PC); } else *** ../vim-8.1.2394/src/testing.c 2019-10-17 22:58:59.070496999 +0200 --- src/testing.c 2019-12-05 21:32:23.119037788 +0100 *************** *** 813,820 **** void f_test_garbagecollect_now(typval_T *argvars UNUSED, typval_T *rettv UNUSED) { ! /* This is dangerous, any Lists and Dicts used internally may be freed ! * while still in use. */ garbage_collect(TRUE); } --- 813,820 ---- void f_test_garbagecollect_now(typval_T *argvars UNUSED, typval_T *rettv UNUSED) { ! // This is dangerous, any Lists and Dicts used internally may be freed ! // while still in use. garbage_collect(TRUE); } *** ../vim-8.1.2394/src/version.c 2019-12-05 21:10:33.731533544 +0100 --- src/version.c 2019-12-05 21:14:09.086796562 +0100 *************** *** 744,745 **** --- 744,747 ---- { /* Add new patch number below this line */ + /**/ + 2395, /**/ -- Some of the well known MS-Windows errors: ESLEEP Operator fell asleep ENOERR No error yet EDOLLAR OS too expensive EWINDOWS MS-Windows loaded, system in danger /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///