diff --git a/.hgtags b/.hgtags index d112ae08aa..1a58e038f9 100644 --- a/.hgtags +++ b/.hgtags @@ -2739,3 +2739,9 @@ bb358cc41d920983629ace62bcf26decbf06cab4 v7-4-010 9801d06e7b4ccdcd02cf40bee34eaaada0ca0409 v7-4-014 a7478f9f2551e95bff138cd658f7a86ced804ab1 v7-4-015 8d5cd0ec3e7183a289f9bac41d3981307cdc1fac v7-4-016 +c47c8cd5fe5c014c141d9fb3fa8935b268436a4e v7-4-017 +460d5be9395ef3e05f4b1397ea98a5b54d825fc5 v7-4-018 +d5eb32dc231cd870c562e7b0be96fa994b505d9f v7-4-019 +c1ae5baa41f47bbf96be81e0158707a88af48b34 v7-4-020 +c514693882b9f1c7be2e76a0307926df799da3ea v7-4-021 +965044860b7f4884657fcaa042853238c7b13e69 v7-4-022 diff --git a/src/edit.c b/src/edit.c index 1de4f2b4e5..c4df2efa8c 100644 --- a/src/edit.c +++ b/src/edit.c @@ -3477,7 +3477,6 @@ ins_compl_new_leader() } compl_enter_selects = !compl_used_match; - compl_shown_match = compl_curr_match = compl_first_match; /* Show the popup menu with a different set of matches. */ ins_compl_show_pum(); @@ -5199,8 +5198,14 @@ ins_complete(c) } else if (ctrl_x_mode == CTRL_X_FILES) { - while (--startcol >= 0 && vim_isfilec(line[startcol])) - ; + char_u *p = line + startcol; + + /* Go back to just before the first filename character. */ + mb_ptr_back(line, p); + while (vim_isfilec(PTR2CHAR(p)) && p >= line) + mb_ptr_back(line, p); + startcol = p - line; + compl_col += ++startcol; compl_length = (int)curs_col - startcol; compl_pattern = addstar(line + compl_col, compl_length, diff --git a/src/misc1.c b/src/misc1.c index 63466dc5a9..a4683af878 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -9180,6 +9180,8 @@ prepare_to_exit() /* * Preserve files and exit. * When called IObuff must contain a message. + * NOTE: This may be called from deathtrap() in a signal handler, avoid unsafe + * functions, such as allocating memory. */ void preserve_exit() @@ -9202,7 +9204,7 @@ preserve_exit() { if (buf->b_ml.ml_mfp != NULL && buf->b_ml.ml_mfp->mf_fname != NULL) { - OUT_STR(_("Vim: preserving files...\n")); + OUT_STR("Vim: preserving files...\n"); screen_start(); /* don't know where cursor is now */ out_flush(); ml_sync_all(FALSE, FALSE); /* preserve all swap files */ @@ -9212,7 +9214,7 @@ preserve_exit() ml_close_all(FALSE); /* close all memfiles, without deleting */ - OUT_STR(_("Vim: Finished.\n")); + OUT_STR("Vim: Finished.\n"); getout(1); } diff --git a/src/os_unix.c b/src/os_unix.c index a1f6928bea..2d8de519eb 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -957,8 +957,10 @@ mch_didjmp() /* * This function handles deadly signals. - * It tries to preserve any swap file and exit properly. + * It tries to preserve any swap files and exit properly. * (partly from Elvis). + * NOTE: Avoid unsafe functions, such as allocating memory, they can result in + * a deadlock. */ static RETSIGTYPE deathtrap SIGDEFARG(sigarg) @@ -1090,18 +1092,23 @@ deathtrap SIGDEFARG(sigarg) } if (entered == 2) { - OUT_STR(_("Vim: Double signal, exiting\n")); + /* No translation, it may call malloc(). */ + OUT_STR("Vim: Double signal, exiting\n"); out_flush(); getout(1); } + /* No translation, it may call malloc(). */ #ifdef SIGHASARG - sprintf((char *)IObuff, _("Vim: Caught deadly signal %s\n"), + sprintf((char *)IObuff, "Vim: Caught deadly signal %s\n", signal_info[i].name); #else - sprintf((char *)IObuff, _("Vim: Caught deadly signal\n")); + sprintf((char *)IObuff, "Vim: Caught deadly signal\n"); #endif - preserve_exit(); /* preserve files and exit */ + + /* Preserve files and exit. This sets the really_exiting flag to prevent + * calling free(). */ + preserve_exit(); #ifdef NBDEBUG reset_signals(); diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c index 5288eb6d3f..30aae8dcce 100644 --- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -4209,10 +4209,11 @@ skip_add: break; case NFA_MCLOSE: - if (nfa_has_zend) + if (nfa_has_zend && (REG_MULTI + ? subs->norm.list.multi[0].end.lnum >= 0 + : subs->norm.list.line[0].end != NULL)) { - /* Do not overwrite the position set by \ze. If no \ze - * encountered end will be set in nfa_regtry(). */ + /* Do not overwrite the position set by \ze. */ subs = addstate(l, state->out, subs, pim, off); break; } @@ -5322,7 +5323,10 @@ nfa_regmatch(prog, start, submatch, m) log_subsexpr(m); #endif nfa_match = TRUE; - break; + /* See comment above at "goto nextchar". */ + if (nextlist->n == 0) + clen = 0; + goto nextchar; case NFA_START_INVISIBLE: case NFA_START_INVISIBLE_FIRST: diff --git a/src/tag.c b/src/tag.c index 8a3c81c817..55ace15bff 100644 --- a/src/tag.c +++ b/src/tag.c @@ -1797,13 +1797,16 @@ line_read_in: */ if (state == TS_START) { - /* The header ends when the line sorts below "!_TAG_". - * There may be non-header items before the header though, - * e.g. "!" itself. When case is folded lower case letters - * sort before "_". */ + /* 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; + /* * Read header line. */ @@ -1898,6 +1901,7 @@ line_read_in: #endif } +parse_line: /* * Figure out where the different strings are in this line. * For "normal" tags: Do a quick check if the tag matches. diff --git a/src/testdir/test64.in b/src/testdir/test64.in index ac3f13d543..e694995cfd 100644 --- a/src/testdir/test64.in +++ b/src/testdir/test64.in @@ -328,6 +328,7 @@ STARTTEST :call add(tl, [2, 'abc \zsmatch\ze abc', 'abc abc abc match abc abc', 'match']) :call add(tl, [2, '\v(a \zsif .*){2}', 'a if then a if last', 'if last', 'a if last']) :call add(tl, [2, '\>\zs.', 'aword. ', '.']) +:call add(tl, [2, '\s\+\ze\[/\|\s\zs\s\+', 'is [a t', ' ']) :" :"""" Tests for \@= and \& features :call add(tl, [2, 'abc\@=', 'abc', 'ab']) @@ -427,6 +428,7 @@ STARTTEST :""""" \@> :call add(tl, [2, '\(a*\)\@>a', 'aaaa']) :call add(tl, [2, '\(a*\)\@>b', 'aaab', 'aaab', 'aaa']) +:call add(tl, [2, '^\(.\{-}b\)\@>.', ' abcbd', ' abc', ' ab']) :" TODO: BT engine does not restore submatch after failure :call add(tl, [1, '\(a*\)\@>a\|a\+', 'aaaa', 'aaaa']) :" diff --git a/src/testdir/test64.ok b/src/testdir/test64.ok index da19c04237..3d117b9957 100644 --- a/src/testdir/test64.ok +++ b/src/testdir/test64.ok @@ -752,6 +752,9 @@ OK 2 - \v(a \zsif .*){2} OK 0 - \>\zs. OK 1 - \>\zs. OK 2 - \>\zs. +OK 0 - \s\+\ze\[/\|\s\zs\s\+ +OK 1 - \s\+\ze\[/\|\s\zs\s\+ +OK 2 - \s\+\ze\[/\|\s\zs\s\+ OK 0 - abc\@= OK 1 - abc\@= OK 2 - abc\@= @@ -983,6 +986,9 @@ OK 2 - \(a*\)\@>a OK 0 - \(a*\)\@>b OK 1 - \(a*\)\@>b OK 2 - \(a*\)\@>b +OK 0 - ^\(.\{-}b\)\@>. +OK 1 - ^\(.\{-}b\)\@>. +OK 2 - ^\(.\{-}b\)\@>. OK 0 - \(a*\)\@>a\|a\+ OK 2 - \(a*\)\@>a\|a\+ OK 0 - \_[^8-9]\+ diff --git a/src/version.c b/src/version.c index 74f361d770..7a38d07133 100644 --- a/src/version.c +++ b/src/version.c @@ -753,6 +753,18 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 22, +/**/ + 21, +/**/ + 20, +/**/ + 19, +/**/ + 18, +/**/ + 17, /**/ 16, /**/