diff --git a/.hgtags b/.hgtags index 42b9e0d8ce..4901299604 100644 --- a/.hgtags +++ b/.hgtags @@ -2758,3 +2758,18 @@ b21b5dcdca2197fc86b9bde77bd6777f0e2d5175 v7-4-031 91f6a28e010d49ae73c13c85dbb8b14c9e5edb36 v7-4-033 22dfcd1494e4f7ea8ddc96e8dd895482e77e3b5a v7-4-034 5481f188dcbb7143596f2d470c7d674bf36efe64 v7-4-035 +90e2f0729a0df249931a2dbe5f4310ba6c91cab4 v7-4-036 +c3d379c2a115b957d82eaa5f2215b688f36a22da v7-4-037 +6daa78b6b99a2ec07d20336db47c9f8165098062 v7-4-038 +4dfba3df303c51fe31efd1255338e9fcbedc5401 v7-4-039 +8336fd924e057d8c797043430325379d9a3ae37b v7-4-040 +408f2a1a953feef25a2c5c96352c82674655e797 v7-4-041 +70915ede509a737ac78c421f43c4447c9682ba41 v7-4-042 +6d11572e2c8b1117b90adf588ff1467b185c1b57 v7-4-043 +c0e3990aed3f179ef006e6de1458e9818c9ab896 v7-4-044 +8ced827b2e8ba49f9ae0da2033670fee83e7b55b v7-4-045 +68056d414f09fccb39219d7fde77fa06769ffa3b v7-4-046 +c21b2f52f1dd003d860e3b574602ed3fdc2b4f1c v7-4-047 +31c9acfeda8f1b84d51a480c1efbb56f384e76b1 v7-4-048 +15c1b8a20da6d650ee3ed0e73c2e3832093b60dd v7-4-049 +eb33cadafcabfc9cb3fc0741e169e84cafec11f8 v7-4-050 diff --git a/runtime/syntax/css.vim b/runtime/syntax/css.vim index daca2e052c..1a70765382 100644 --- a/runtime/syntax/css.vim +++ b/runtime/syntax/css.vim @@ -6,7 +6,7 @@ " Nikolai Weibull (Add CSS2 support) " Maintainer: Jules Wang " URL: https://github.com/JulesWang/css.vim -" Last Change: 2013 Aug 28 +" Last Change: 2013 Sep 24 " For version 5.x: Clear all syntax items " For version 6.x: Quit when a syntax file was already loaded @@ -21,9 +21,6 @@ elseif exists("b:current_syntax") && b:current_syntax == "css" finish endif -" Required for cssHacks -setlocal iskeyword-=_ - let s:cpo_save = &cpo set cpo&vim @@ -77,23 +74,20 @@ syn match cssValueAngle contained "[-+]\=\d\+\(\.\d*\)\=\(deg\|grad\|rad\)" cont syn match cssValueTime contained "+\=\d\+\(\.\d*\)\=\(ms\|s\)" contains=cssUnitDecorators syn match cssValueFrequency contained "+\=\d\+\(\.\d*\)\=\(Hz\|kHz\)" contains=cssUnitDecorators - " @media -syn match cssMedia "@media\>" nextgroup=cssMediaType,cssMediaFeature,cssMediaBlock,cssMediaComma,cssMediaKeyword2 skipwhite skipnl -syn keyword cssMediaType contained screen print aural braille embossed handheld projection tty tv all contained skipwhite skipnl nextgroup=cssMediaFeature,cssMediaBlock -syn match cssMediaFeature /\(and\)\=\s*(.\{-})/ contained skipwhite skipnl contains=cssMediaProp,cssValueLength,cssMediaKeyword,cssValueInteger,cssMediaAttr,cssVendor nextgroup=cssMediaFeature,cssMediaBlock,cssMediaComma -syn keyword cssMediaKeyword and contained -syn keyword cssMediaKeyword2 only not contained nextgroup=cssMediaType skipwhite skipnl - +syn match cssMedia "@media\>" nextgroup=cssMediaQuery,cssMediaBlock skipwhite skipnl +syn match cssMediaQuery /\(only\|not\)\=\s*[a-z]*\(\s\|,\)\@=\(\(\s\+and\)\=\s\+(.\{-})\)*/ contained skipwhite skipnl contains=cssMediaProp,cssValueLength,cssMediaKeyword,cssValueInteger,cssMediaAttr,cssVendor,cssMediaType nextgroup=cssMediaBlock,cssMediaComma +syn keyword cssMediaType contained screen print aural braille embossed handheld projection tty tv speech all contained skipwhite skipnl +syn keyword cssMediaKeyword only not and contained syn region cssMediaBlock transparent matchgroup=cssBraces start='{' end='}' contains=css.*Attr,css.*Prop,cssComment,cssValue.*,cssColor,cssURL,cssImportant,cssError,cssStringQ,cssStringQQ,cssFunction,cssUnicodeEscape,cssVendor,cssDefinition,cssTagName,cssClassName,cssIdentifier,cssPseudoClass,cssSelectorOp,cssSelectorOp2,cssAttributeSelector fold -syn match cssMediaComma "," nextgroup=cssMediaType,cssMediaKeyword2 skipwhite skipnl contained +syn match cssMediaComma "," nextgroup=cssMediaQuery skipwhite skipnl contained " Reference: http://www.w3.org/TR/css3-mediaqueries/ -syn keyword cssMediaProp contained width height orientation monochrome scan grid +syn keyword cssMediaProp contained width height orientation scan grid syn match cssMediaProp contained /\(\(device\)-\)\=aspect-ratio/ syn match cssMediaProp contained /\(\(max\|min\)-\)\=device-pixel-ratio/ syn match cssMediaProp contained /\(\(max\|min\)-\)\=device-\(height\|width\)/ -syn match cssMediaProp contained /\(\(max\|min\)-\)\=\(height\|width\|resolution\|color\(-index\)\=\)/ +syn match cssMediaProp contained /\(\(max\|min\)-\)\=\(height\|width\|resolution\|monochrome\|color\(-index\)\=\)/ syn keyword cssMediaAttr contained portrait landscape progressive interlace " @page @@ -103,14 +97,15 @@ syn match cssPageHeaderProp /@\(\(top\|left\|right\|bottom\)-\(left\|center\|rig syn keyword cssPageProp content size contained " @keyframe -syn match cssKeyFrame "@\(-.*-\)\=keyframes\>\(\s*\<\S*\>\)\=" nextgroup=cssKeyFrameBlock contains=cssVendor skipwhite skipnl +syn match cssKeyFrame "@\(-[a-z]*-\)\=keyframes\>\(\s*\<\S*\>\)\=" nextgroup=cssKeyFrameBlock contains=cssVendor skipwhite skipnl syn region cssKeyFrameBlock contained transparent matchgroup=cssBraces start="{" end="}" contains=cssKeyFrameSelector,cssDefinition syn match cssKeyFrameSelector /\(\d*%\|from\|to\)\=/ contained skipwhite skipnl " @import -syn region cssInclude start=/@import\>/ end=/\ze;/ contains=cssComment,cssURL,cssUnicodeEscape,cssMediaType,cssStringQ,cssStringQQ -syn region cssInclude start=/@charset\>/ end=/\ze;/ contains=cssStringQ,cssStringQQ,cssUnicodeEscape,cssComment -syn region cssInclude start=/@namespace\>/ end=/\ze;/ contains=cssStringQ,cssStringQQ,cssUnicodeEscape,cssComment +syn region cssInclude start=/@import\>/ end=/\ze;/ contains=cssComment,cssURL,cssUnicodeEscape,cssMediaQuery,cssStringQ,cssStringQQ,cssIncludeKeyword +syn region cssInclude start=/@charset\>/ end=/\ze;/ contains=cssStringQ,cssStringQQ,cssUnicodeEscape,cssComment,cssIncludeKeyword +syn region cssInclude start=/@namespace\>/ end=/\ze;/ contains=cssStringQ,cssStringQQ,cssUnicodeEscape,cssComment,cssIncludeKeyword +syn match cssIncludeKeyword /\(@import\|@charset\|@namespace\)/ contained " @font-face " http://www.w3.org/TR/css3-fonts/#at-font-face-rule @@ -458,7 +453,7 @@ syn match cssPseudoClassId contained "\<\(input-\)\=placeholder\>" " Comment -syn region cssComment start="/\*" end="\*/" contains=@Spell +syn region cssComment start="/\*" end="\*/" contains=@Spell fold syn match cssUnicodeEscape "\\\x\{1,6}\s\?" syn match cssSpecialCharQQ +\\"+ contained @@ -593,6 +588,7 @@ if version >= 508 || !exists("did_css_syn_inits") HiLink cssColor Constant HiLink cssIdentifier Function HiLink cssInclude Include + HiLink cssIncludeKeyword atKeyword HiLink cssImportant Special HiLink cssBraces Function HiLink cssBraceError Error @@ -602,19 +598,17 @@ if version >= 508 || !exists("did_css_syn_inits") HiLink cssStringQQ String HiLink cssStringQ String HiLink cssAttributeSelector String - HiLink cssMedia Special + HiLink cssMedia atKeyword HiLink cssMediaType Special HiLink cssMediaComma Normal - HiLink cssMediaFeature Normal HiLink cssMediaKeyword Statement - HiLink cssMediaKeyword2 Statement HiLink cssMediaProp cssProp HiLink cssMediaAttr cssAttr - HiLink cssPage Special + HiLink cssPage atKeyword HiLink cssPagePseudo PreProc HiLink cssPageHeaderProp PreProc HiLink cssPageProp cssProp - HiLink cssKeyFrame Special + HiLink cssKeyFrame atKeyword HiLink cssKeyFrameSelector Constant HiLink cssFontDescriptor Special HiLink cssFontDescriptorFunction Constant @@ -626,6 +620,7 @@ if version >= 508 || !exists("did_css_syn_inits") HiLink cssAttr Constant HiLink cssUnitDecorators Number HiLink cssNoise Noise + HiLink atKeyword Comment delcommand HiLink endif diff --git a/src/auto/configure b/src/auto/configure index 2eb702c5e6..83c2f137e3 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -3643,6 +3643,24 @@ if test "$GCC" = yes; then fi fi +{ echo "$as_me:$LINENO: checking for recent clang version" >&5 +echo $ECHO_N "checking for recent clang version... $ECHO_C" >&6; } +CLANG_VERSION_STRING=`"$CC" --version 2>/dev/null | sed -n -e 's/^.*clang.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$/\1/p'` +if test x"$CLANG_VERSION_STRING" != x"" ; then + CLANG_MAJOR=`echo "$CLANG_VERSION_STRING" | sed -n -e 's/\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*/\1/p'` + CLANG_MINOR=`echo "$CLANG_VERSION_STRING" | sed -n -e 's/[0-9][0-9]*\.\([0-9][0-9]*\)\.[0-9][0-9]*/\1/p'` + CLANG_REVISION=`echo "$CLANG_VERSION_STRING" | sed -n -e 's/[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\)/\1/p'` + CLANG_VERSION=`expr $CLANG_MAJOR '*' 1000000 '+' $CLANG_MINOR '*' 1000 '+' $CLANG_REVISION` + { echo "$as_me:$LINENO: result: $CLANG_VERSION" >&5 +echo "${ECHO_T}$CLANG_VERSION" >&6; } + if test "$CLANG_VERSION" -ge 500002075 ; then + CFLAGS=`echo "$CFLAGS" | sed -n -e 's/-fno-strength-reduce/ /p'` + fi +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + if test "$cross_compiling" = yes; then { echo "$as_me:$LINENO: result: cannot compile a simple program; if not cross compiling check CC and CFLAGS" >&5 echo "${ECHO_T}cannot compile a simple program; if not cross compiling check CC and CFLAGS" >&6; } diff --git a/src/configure.in b/src/configure.in index ba5e03c32b..c3a5336d5d 100644 --- a/src/configure.in +++ b/src/configure.in @@ -62,6 +62,29 @@ if test "$GCC" = yes; then fi fi +dnl clang-500.2.75 or around has abandoned -f[no-]strength-reduce and issues a +dnl warning when that flag is passed to. Accordingly, adjust CFLAGS based on +dnl the version number of the clang in use. +dnl Note that this does not work to get the version of clang 3.1 or 3.2. +AC_MSG_CHECKING(for recent clang version) +CLANG_VERSION_STRING=`"$CC" --version 2>/dev/null | sed -n -e 's/^.*clang.*\([[0-9]][[0-9]]*\.[[0-9]][[0-9]]*\.[[0-9]][[0-9]]*\).*$/\1/p'` +if test x"$CLANG_VERSION_STRING" != x"" ; then + CLANG_MAJOR=`echo "$CLANG_VERSION_STRING" | sed -n -e 's/\([[0-9]][[0-9]]*\)\.[[0-9]][[0-9]]*\.[[0-9]][[0-9]]*/\1/p'` + CLANG_MINOR=`echo "$CLANG_VERSION_STRING" | sed -n -e 's/[[0-9]][[0-9]]*\.\([[0-9]][[0-9]]*\)\.[[0-9]][[0-9]]*/\1/p'` + CLANG_REVISION=`echo "$CLANG_VERSION_STRING" | sed -n -e 's/[[0-9]][[0-9]]*\.[[0-9]][[0-9]]*\.\([[0-9]][[0-9]]*\)/\1/p'` + CLANG_VERSION=`expr $CLANG_MAJOR '*' 1000000 '+' $CLANG_MINOR '*' 1000 '+' $CLANG_REVISION` + AC_MSG_RESULT($CLANG_VERSION) + dnl If you find the same issue with versions earlier than 500.2.75, + dnl change the constant 500002075 below appropriately. To get the + dnl integer corresponding to a version number, refer to the + dnl definition of CLANG_VERSION above. + if test "$CLANG_VERSION" -ge 500002075 ; then + CFLAGS=`echo "$CFLAGS" | sed -n -e 's/-fno-strength-reduce/ /p'` + fi +else + AC_MSG_RESULT(no) +fi + dnl If configure thinks we are cross compiling, there might be something dnl wrong with the CC or CFLAGS settings, give a useful warning message if test "$cross_compiling" = yes; then diff --git a/src/eval.c b/src/eval.c index 998c286565..694e73c271 100644 --- a/src/eval.c +++ b/src/eval.c @@ -915,12 +915,13 @@ eval_clear() /* autoloaded script names */ ga_clear_strings(&ga_loaded); - /* script-local variables */ + /* Script-local variables. First clear all the variables and in a second + * loop free the scriptvar_T, because a variable in one script might hold + * a reference to the whole scope of another script. */ for (i = 1; i <= ga_scripts.ga_len; ++i) - { vars_clear(&SCRIPT_VARS(i)); + for (i = 1; i <= ga_scripts.ga_len; ++i) vim_free(SCRIPT_SV(i)); - } ga_clear(&ga_scripts); /* unreferenced lists and dicts */ @@ -13073,9 +13074,18 @@ get_user_input(argvars, rettv, inputdialog) } if (defstr != NULL) + { +# ifdef FEAT_EX_EXTRA + int save_ex_normal_busy = ex_normal_busy; + ex_normal_busy = 0; +# endif rettv->vval.v_string = getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr, xp_type, xp_arg); +# ifdef FEAT_EX_EXTRA + ex_normal_busy = save_ex_normal_busy; +# endif + } if (inputdialog && rettv->vval.v_string == NULL && argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) @@ -24328,6 +24338,7 @@ do_string_sub(str, pat, sub, flags) garray_T ga; char_u *ret; char_u *save_cpo; + int zero_width; /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ save_cpo = p_cpo; @@ -24366,20 +24377,17 @@ do_string_sub(str, pat, sub, flags) (void)vim_regsub(®match, sub, (char_u *)ga.ga_data + ga.ga_len + i, TRUE, TRUE, FALSE); ga.ga_len += i + sublen - 1; - /* avoid getting stuck on a match with an empty string */ - if (tail == regmatch.endp[0]) + zero_width = (tail == regmatch.endp[0] + || regmatch.startp[0] == regmatch.endp[0]); + tail = regmatch.endp[0]; + if (*tail == NUL) + break; + if (zero_width) { - if (*tail == NUL) - break; + /* avoid getting stuck on a match with an empty string */ *((char_u *)ga.ga_data + ga.ga_len) = *tail++; ++ga.ga_len; } - else - { - tail = regmatch.endp[0]; - if (*tail == NUL) - break; - } if (!do_all) break; } diff --git a/src/ex_cmds.c b/src/ex_cmds.c index b79a259116..76cc8f6d23 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -4740,11 +4740,17 @@ do_sub(eap) char_u *resp; colnr_T sc, ec; - print_line_no_prefix(lnum, FALSE, FALSE); + print_line_no_prefix(lnum, do_number, do_list); getvcol(curwin, &curwin->w_cursor, &sc, NULL, NULL); curwin->w_cursor.col = regmatch.endpos[0].col - 1; getvcol(curwin, &curwin->w_cursor, NULL, NULL, &ec); + if (do_number || curwin->w_p_nu) + { + int numw = number_width(curwin) + 1; + sc += numw; + ec += numw; + } msg_start(); for (i = 0; i < (long)sc; ++i) msg_putchar(' '); diff --git a/src/if_tcl.c b/src/if_tcl.c index be9cd64cb3..b798ea59ab 100644 --- a/src/if_tcl.c +++ b/src/if_tcl.c @@ -165,6 +165,7 @@ typedef int HANDLE; */ static HANDLE hTclLib = NULL; Tcl_Interp* (*dll_Tcl_CreateInterp)(); +void (*dll_Tcl_FindExecutable)(const void *); /* * Table of name to function pointer of tcl. @@ -175,6 +176,7 @@ static struct { TCL_PROC* ptr; } tcl_funcname_table[] = { {"Tcl_CreateInterp", (TCL_PROC*)&dll_Tcl_CreateInterp}, + {"Tcl_FindExecutable", (TCL_PROC*)&dll_Tcl_FindExecutable}, {NULL, NULL}, }; @@ -248,11 +250,12 @@ tcl_enabled(verbose) { Tcl_Interp *interp; + dll_Tcl_FindExecutable(find_executable_arg); + if (interp = dll_Tcl_CreateInterp()) { if (Tcl_InitStubs(interp, DYNAMIC_TCL_VER, 0)) { - Tcl_FindExecutable(find_executable_arg); Tcl_DeleteInterp(interp); stubs_initialized = TRUE; } diff --git a/src/main.c b/src/main.c index d43d44c035..a294cf031a 100644 --- a/src/main.c +++ b/src/main.c @@ -834,7 +834,7 @@ vim_main2(int argc UNUSED, char **argv UNUSED) starttermcap(); /* start termcap if not done by wait_return() */ TIME_MSG("start termcap"); #if defined(FEAT_TERMRESPONSE) && defined(FEAT_MBYTE) - may_req_ambiguous_character_width(); + may_req_ambiguous_char_width(); #endif #ifdef FEAT_MOUSE diff --git a/src/normal.c b/src/normal.c index 39431d4dc3..0651196561 100644 --- a/src/normal.c +++ b/src/normal.c @@ -5271,8 +5271,12 @@ dozet: { pos_T pos = curwin->w_cursor; - /* Find bad word under the cursor. */ + /* Find bad word under the cursor. When 'spell' is + * off this fails and find_ident_under_cursor() is + * used below. */ + emsg_off++; len = spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL); + emsg_off--; if (len != 0 && curwin->w_cursor.col <= pos.col) ptr = ml_get_pos(&curwin->w_cursor); curwin->w_cursor = pos; diff --git a/src/ops.c b/src/ops.c index db5a182c19..b1f75a1eab 100644 --- a/src/ops.c +++ b/src/ops.c @@ -3808,9 +3808,6 @@ do_put(regname, dir, count, flags) FALSE /* stop after 1 paste */ #endif ); -#ifdef FEAT_VISUAL - VIsual_active = FALSE; -#endif curbuf->b_op_end = curwin->w_cursor; /* For "CTRL-O p" in Insert mode, put cursor after last char */ @@ -3972,6 +3969,10 @@ end: if (regname == '=') vim_free(y_array); +#ifdef FEAT_VISUAL + VIsual_active = FALSE; +#endif + /* If the cursor is past the end of the line put it at the end. */ adjust_cursor_eol(); } diff --git a/src/os_mswin.c b/src/os_mswin.c index 67b7960978..95c3d17380 100644 --- a/src/os_mswin.c +++ b/src/os_mswin.c @@ -498,6 +498,104 @@ slash_adjust(p) } } +#if (_MSC_VER >= 1300) +# define OPEN_OH_ARGTYPE intptr_t +#else +# define OPEN_OH_ARGTYPE long +#endif + + static int +stat_symlink_aware(const char *name, struct stat *stp) +{ +#if defined(_MSC_VER) && _MSC_VER < 1700 + /* Work around for VC10 or earlier. stat() can't handle symlinks properly. + * VC9 or earlier: stat() doesn't support a symlink at all. It retrieves + * status of a symlink itself. + * VC10: stat() supports a symlink to a normal file, but it doesn't support + * a symlink to a directory (always returns an error). */ + WIN32_FIND_DATA findData; + HANDLE hFind, h; + DWORD attr = 0; + BOOL is_symlink = FALSE; + + hFind = FindFirstFile(name, &findData); + if (hFind != INVALID_HANDLE_VALUE) + { + attr = findData.dwFileAttributes; + if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) + && (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) + is_symlink = TRUE; + FindClose(hFind); + } + if (is_symlink) + { + h = CreateFile(name, FILE_READ_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, + (attr & FILE_ATTRIBUTE_DIRECTORY) + ? FILE_FLAG_BACKUP_SEMANTICS : 0, + NULL); + if (h != INVALID_HANDLE_VALUE) + { + int fd, n; + + fd = _open_osfhandle((OPEN_OH_ARGTYPE)h, _O_RDONLY); + n = _fstat(fd, (struct _stat*)stp); + _close(fd); + return n; + } + } +#endif + return stat(name, stp); +} + +#ifdef FEAT_MBYTE + static int +wstat_symlink_aware(const WCHAR *name, struct _stat *stp) +{ +# if defined(_MSC_VER) && _MSC_VER < 1700 + /* Work around for VC10 or earlier. _wstat() can't handle symlinks properly. + * VC9 or earlier: _wstat() doesn't support a symlink at all. It retrieves + * status of a symlink itself. + * VC10: _wstat() supports a symlink to a normal file, but it doesn't + * support a symlink to a directory (always returns an error). */ + int n; + BOOL is_symlink = FALSE; + HANDLE hFind, h; + DWORD attr = 0; + WIN32_FIND_DATAW findDataW; + + hFind = FindFirstFileW(name, &findDataW); + if (hFind != INVALID_HANDLE_VALUE) + { + attr = findDataW.dwFileAttributes; + if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) + && (findDataW.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) + is_symlink = TRUE; + FindClose(hFind); + } + if (is_symlink) + { + h = CreateFileW(name, FILE_READ_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, + (attr & FILE_ATTRIBUTE_DIRECTORY) + ? FILE_FLAG_BACKUP_SEMANTICS : 0, + NULL); + if (h != INVALID_HANDLE_VALUE) + { + int fd; + + fd = _open_osfhandle((OPEN_OH_ARGTYPE)h, _O_RDONLY); + n = _fstat(fd, stp); + _close(fd); + return n; + } + } +# endif + return _wstat(name, stp); +} +#endif /* * stat() can't handle a trailing '/' or '\', remove it first. @@ -534,7 +632,7 @@ vim_stat(const char *name, struct stat *stp) if (wp != NULL) { - n = _wstat(wp, (struct _stat *)stp); + n = wstat_symlink_aware(wp, (struct _stat *)stp); vim_free(wp); if (n >= 0) return n; @@ -544,7 +642,7 @@ vim_stat(const char *name, struct stat *stp) } } #endif - return stat(buf, stp); + return stat_symlink_aware(buf, stp); } #if defined(FEAT_GUI_MSWIN) || defined(PROTO) diff --git a/src/os_win32.c b/src/os_win32.c index f36dfb3db9..cd29b8738a 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -78,16 +78,6 @@ # endif #endif -/* - * Reparse Point - */ -#ifndef FILE_ATTRIBUTE_REPARSE_POINT -# define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 -#endif -#ifndef IO_REPARSE_TAG_SYMLINK -# define IO_REPARSE_TAG_SYMLINK 0xA000000C -#endif - /* Record all output and all keyboard & mouse input */ /* #define MCH_WRITE_DUMP */ diff --git a/src/os_win32.h b/src/os_win32.h index 58b179ff87..29fe5e4fb8 100644 --- a/src/os_win32.h +++ b/src/os_win32.h @@ -130,6 +130,19 @@ # define DFLT_MAXMEMTOT (5*1024) /* use up to 5 Mbyte for Vim */ #endif +/* + * Reparse Point + */ +#ifndef FILE_ATTRIBUTE_REPARSE_POINT +# define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 +#endif +#ifndef IO_REPARSE_TAG_MOUNT_POINT +# define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003 +#endif +#ifndef IO_REPARSE_TAG_SYMLINK +# define IO_REPARSE_TAG_SYMLINK 0xA000000C +#endif + #if defined(_MSC_VER) || defined(__BORLANDC__) /* Support for __try / __except. All versions of MSVC and Borland C are * expected to have this. Any other compilers that support it? */ diff --git a/src/proto/term.pro b/src/proto/term.pro index 25d9b96a03..b3d0df39d8 100644 --- a/src/proto/term.pro +++ b/src/proto/term.pro @@ -35,7 +35,7 @@ void settmode __ARGS((int tmode)); void starttermcap __ARGS((void)); void stoptermcap __ARGS((void)); void may_req_termresponse __ARGS((void)); -void may_req_ambiguous_character_width __ARGS((void)); +void may_req_ambiguous_char_width __ARGS((void)); int swapping_screen __ARGS((void)); void setmouse __ARGS((void)); int mouse_has __ARGS((int c)); diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c index cc3a8b64b8..216459c4d0 100644 --- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -36,7 +36,7 @@ enum { NFA_SPLIT = -1024, NFA_MATCH, - NFA_SKIP_CHAR, /* matches a 0-length char */ + NFA_EMPTY, /* matches 0-length */ NFA_START_COLL, /* [abc] start */ NFA_END_COLL, /* [abc] end */ @@ -2005,8 +2005,8 @@ nfa_regpiece() { /* Ignore result of previous call to nfa_regatom() */ post_ptr = post_start + my_post_start; - /* NFA_SKIP_CHAR has 0-length and works everywhere */ - EMIT(NFA_SKIP_CHAR); + /* NFA_EMPTY is 0-length and works everywhere */ + EMIT(NFA_EMPTY); return OK; } @@ -2170,16 +2170,16 @@ nfa_regbranch() old_post_pos = (int)(post_ptr - post_start); if (nfa_regconcat() == FAIL) return FAIL; - /* if concat is empty, skip a input char. But do emit a node */ + /* if concat is empty do emit a node */ if (old_post_pos == (int)(post_ptr - post_start)) - EMIT(NFA_SKIP_CHAR); + EMIT(NFA_EMPTY); EMIT(NFA_CONCAT); ch = peekchr(); } - /* Even if a branch is empty, emit one node for it */ + /* if a branch is empty, emit one node for it */ if (old_post_pos == (int)(post_ptr - post_start)) - EMIT(NFA_SKIP_CHAR); + EMIT(NFA_EMPTY); return OK; } @@ -2423,7 +2423,7 @@ nfa_set_code(c) case NFA_STAR_NONGREEDY: STRCPY(code, "NFA_STAR_NONGREEDY "); break; case NFA_QUEST: STRCPY(code, "NFA_QUEST"); break; case NFA_QUEST_NONGREEDY: STRCPY(code, "NFA_QUEST_NON_GREEDY"); break; - case NFA_SKIP_CHAR: STRCPY(code, "NFA_SKIP_CHAR"); break; + case NFA_EMPTY: STRCPY(code, "NFA_EMPTY"); break; case NFA_OR: STRCPY(code, "NFA_OR"); break; case NFA_START_COLL: STRCPY(code, "NFA_START_COLL"); break; @@ -3067,7 +3067,7 @@ nfa_max_width(startstate, depth) case NFA_ZSTART: case NFA_ZEND: case NFA_OPT_CHARS: - case NFA_SKIP_CHAR: + case NFA_EMPTY: case NFA_START_PATTERN: case NFA_END_PATTERN: case NFA_COMPOSING: @@ -3265,15 +3265,14 @@ post2nfa(postfix, end, nfa_calc_size) PUSH(frag(e1.start, e2.out)); break; - case NFA_SKIP_CHAR: - /* Symbol of 0-length, Used in a repetition - * with max/min count of 0 */ + case NFA_EMPTY: + /* 0-length, used in a repetition with max/min count of 0 */ if (nfa_calc_size == TRUE) { nstate++; break; } - s = alloc_state(NFA_SKIP_CHAR, NULL, NULL); + s = alloc_state(NFA_EMPTY, NULL, NULL); if (s == NULL) goto theend; PUSH(frag(s, list1(&s->out))); @@ -3823,6 +3822,7 @@ static void copy_pim __ARGS((nfa_pim_T *to, nfa_pim_T *from)); static void clear_sub __ARGS((regsub_T *sub)); static void copy_sub __ARGS((regsub_T *to, regsub_T *from)); static void copy_sub_off __ARGS((regsub_T *to, regsub_T *from)); +static void copy_ze_off __ARGS((regsub_T *to, regsub_T *from)); static int sub_equal __ARGS((regsub_T *sub1, regsub_T *sub2)); static int match_backref __ARGS((regsub_T *sub, int subidx, int *bytelen)); static int has_state_with_pos __ARGS((nfa_list_T *l, nfa_state_T *state, regsubs_T *subs, nfa_pim_T *pim)); @@ -3909,6 +3909,29 @@ copy_sub_off(to, from) } } +/* + * Like copy_sub() but only do the end of the main match if \ze is present. + */ + static void +copy_ze_off(to, from) + regsub_T *to; + regsub_T *from; +{ + if (nfa_has_zend) + { + if (REG_MULTI) + { + if (from->list.multi[0].end.lnum >= 0) + to->list.multi[0].end = from->list.multi[0].end; + } + else + { + if (from->list.line[0].end != NULL) + to->list.line[0].end = from->list.line[0].end; + } + } +} + /* * Return TRUE if "sub1" and "sub2" have the same start positions. */ @@ -4209,7 +4232,7 @@ addstate(l, state, subs_arg, pim, off) case NFA_MOPEN: case NFA_ZEND: case NFA_SPLIT: - case NFA_SKIP_CHAR: + case NFA_EMPTY: /* These nodes are not added themselves but their "out" and/or * "out1" may be added below. */ break; @@ -4337,7 +4360,7 @@ skip_add: subs = addstate(l, state->out1, subs, pim, off); break; - case NFA_SKIP_CHAR: + case NFA_EMPTY: case NFA_NOPEN: case NFA_NCLOSE: subs = addstate(l, state->out, subs, pim, off); @@ -5309,6 +5332,7 @@ find_match_text(startcol, regstart, match_text) * When "nfa_endp" is not NULL it is a required end-of-match position. * * Return TRUE if there is a match, FALSE otherwise. + * When there is a match "submatch" contains the positions. * Note: Caller must ensure that: start != NULL. */ static int @@ -5604,9 +5628,13 @@ nfa_regmatch(prog, start, submatch, m) { int in_use = m->norm.in_use; - /* Copy submatch info for the recursive call, so that - * \1 can be matched. */ + /* Copy submatch info for the recursive call, opposite + * of what happens on success below. */ copy_sub_off(&m->norm, &t->subs.norm); +#ifdef FEAT_SYN_HL + if (nfa_has_zsubexpr) + copy_sub_off(&m->synt, &t->subs.synt); +#endif /* * First try matching the invisible match, then what @@ -5630,6 +5658,9 @@ nfa_regmatch(prog, start, submatch, m) if (nfa_has_zsubexpr) copy_sub_off(&t->subs.synt, &m->synt); #endif + /* If the pattern has \ze and it matched in the + * sub pattern, use it. */ + copy_ze_off(&t->subs.norm, &m->norm); /* t->state->out1 is the corresponding * END_INVISIBLE node; Add its out to the current @@ -5713,6 +5744,13 @@ nfa_regmatch(prog, start, submatch, m) #endif break; } + /* Copy submatch info to the recursive call, opposite of what + * happens afterwards. */ + copy_sub_off(&m->norm, &t->subs.norm); +#ifdef FEAT_SYN_HL + if (nfa_has_zsubexpr) + copy_sub_off(&m->synt, &t->subs.synt); +#endif /* First try matching the pattern. */ result = recursive_regmatch(t->state, NULL, prog, diff --git a/src/search.c b/src/search.c index ac39b6b79c..2ce2961671 100644 --- a/src/search.c +++ b/src/search.c @@ -4689,8 +4689,8 @@ is_one_char(pattern) && regmatch.startpos[0].lnum == regmatch.endpos[0].lnum && regmatch.startpos[0].col == regmatch.endpos[0].col); - if (!result && incl(&pos) == 0 && pos.col == regmatch.endpos[0].col) - result = TRUE; + if (!result && inc(&pos) >= 0 && pos.col == regmatch.endpos[0].col) + result = TRUE; } called_emsg |= save_called_emsg; diff --git a/src/spell.c b/src/spell.c index 20344f25fe..2972fe9154 100644 --- a/src/spell.c +++ b/src/spell.c @@ -9479,7 +9479,8 @@ spell_add_word(word, len, bad, idx, undo) if (undo) { home_replace(NULL, fname, NameBuff, MAXPATHL, TRUE); - smsg((char_u *)_("Word removed from %s"), NameBuff); + smsg((char_u *)_("Word '%.*s' removed from %s"), + len, word, NameBuff); } } fseek(fd, fpos_next, SEEK_SET); @@ -9525,7 +9526,7 @@ spell_add_word(word, len, bad, idx, undo) fclose(fd); home_replace(NULL, fname, NameBuff, MAXPATHL, TRUE); - smsg((char_u *)_("Word added to %s"), NameBuff); + smsg((char_u *)_("Word '%.*s' added to %s"), len, word, NameBuff); } } @@ -10135,7 +10136,7 @@ spell_check_sps() } /* - * "z?": Find badly spelled word under or after the cursor. + * "z=": Find badly spelled word under or after the cursor. * Give suggestions for the properly spelled word. * In Visual mode use the highlighted word as the bad word. * When "count" is non-zero use that suggestion. @@ -15568,11 +15569,21 @@ ex_spellinfo(eap) ex_spelldump(eap) exarg_T *eap; { + char_u *spl; + long dummy; + if (no_spell_checking(curwin)) return; + get_option_value((char_u*)"spl", &dummy, &spl, OPT_LOCAL); - /* Create a new empty buffer by splitting the window. */ + /* 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); + if (!bufempty() || !buf_valid(curbuf)) return; diff --git a/src/term.c b/src/term.c index d4e4e0d9a0..763f8e782f 100644 --- a/src/term.c +++ b/src/term.c @@ -3356,7 +3356,7 @@ may_req_termresponse() * it must be called immediately after entering termcap mode. */ void -may_req_ambiguous_character_width() +may_req_ambiguous_char_width() { if (u7_status == U7_GET && cur_tmode == TMODE_RAW diff --git a/src/testdir/test53.in b/src/testdir/test53.in index 2cc7d10508..47cf6f562f 100644 --- a/src/testdir/test53.in +++ b/src/testdir/test53.in @@ -46,6 +46,9 @@ vlgnd :set selection=exclusive $cgNmongoose/i cgnj +:" Make sure there is no other match y uppercase. +/x59 +gggnd :/^start:/,/^end:/wq! test.out ENDTEST @@ -75,4 +78,7 @@ delete first and last chars uniquepattern uniquepattern my very excellent mother just served us nachos for (i=0; i<=10; i++) +Y +text +Y end: diff --git a/src/testdir/test53.ok b/src/testdir/test53.ok index 40031ed47a..e469869abb 100644 --- a/src/testdir/test53.ok +++ b/src/testdir/test53.ok @@ -27,4 +27,7 @@ elete first and last char uniquepattern my very excellent mongoose just served us nachos for (j=0; i<=10; i++) + +text +Y end: diff --git a/src/testdir/test64.in b/src/testdir/test64.in index 7a20e1836c..2df9a6b60e 100644 --- a/src/testdir/test64.in +++ b/src/testdir/test64.in @@ -425,11 +425,13 @@ STARTTEST :" :" complicated look-behind match :call add(tl, [2, '\(r\@<=\|\w\@ :call add(tl, [2, '\(a*\)\@>a', 'aaaa']) :call add(tl, [2, '\(a*\)\@>b', 'aaab', 'aaab', 'aaa']) :call add(tl, [2, '^\(.\{-}b\)\@>.', ' abcbd', ' abc', ' ab']) +:call add(tl, [2, '\(.\{-}\)\(\)\@>$', 'abc', 'abc', 'abc', '']) :" 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 53affcd7e8..401da4071d 100644 --- a/src/testdir/test64.ok +++ b/src/testdir/test64.ok @@ -983,6 +983,9 @@ OK 2 - \(foo\)\@<=.* OK 0 - \(r\@<=\|\w\@a OK 1 - \(a*\)\@>a OK 2 - \(a*\)\@>a @@ -992,6 +995,9 @@ OK 2 - \(a*\)\@>b OK 0 - ^\(.\{-}b\)\@>. OK 1 - ^\(.\{-}b\)\@>. OK 2 - ^\(.\{-}b\)\@>. +OK 0 - \(.\{-}\)\(\)\@>$ +OK 1 - \(.\{-}\)\(\)\@>$ +OK 2 - \(.\{-}\)\(\)\@>$ OK 0 - \(a*\)\@>a\|a\+ OK 2 - \(a*\)\@>a\|a\+ OK 0 - \_[^8-9]\+ diff --git a/src/testdir/test80.in b/src/testdir/test80.in index 7f6ecfccb5..5491a90092 100644 --- a/src/testdir/test80.in +++ b/src/testdir/test80.in @@ -142,6 +142,8 @@ STARTTEST :$put =\"\n\nTEST_7:\" :$put =substitute('A A', 'A.', '\=submatch(0)', '') :$put =substitute(\"B\nB\", 'B.', '\=submatch(0)', '') +:$put =substitute('-bb', '\zeb', 'a', 'g') +:$put =substitute('-bb', '\ze', 'c', 'g') /^TEST_8 ENDTEST diff --git a/src/testdir/test80.ok b/src/testdir/test80.ok index 45b1d1d0f1..562bbf249c 100644 --- a/src/testdir/test80.ok +++ b/src/testdir/test80.ok @@ -103,6 +103,8 @@ TEST_7: A A B B +-abab +c-cbcbc TEST_8: diff --git a/src/version.c b/src/version.c index 3d3f1dbe9e..942b5bcee5 100644 --- a/src/version.c +++ b/src/version.c @@ -753,6 +753,36 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 50, +/**/ + 49, +/**/ + 48, +/**/ + 47, +/**/ + 46, +/**/ + 45, +/**/ + 44, +/**/ + 43, +/**/ + 42, +/**/ + 41, +/**/ + 40, +/**/ + 39, +/**/ + 38, +/**/ + 37, +/**/ + 36, /**/ 35, /**/