diff -ubBwrN ../../work/vim74/Filelist ./Filelist --- ../../work/vim74/Filelist 2013-07-13 16:23:38.000000000 +0300 +++ ./Filelist 2014-02-22 19:30:45.000000000 +0300 @@ -80,6 +80,7 @@ src/main.aap \ src/testdir/main.aap \ src/testdir/*.in \ + src/testdir/sautest/autoload/*.vim \ src/testdir/test[0-9]*.ok \ src/testdir/test49.vim \ src/testdir/test60.vim \ diff -ubBwrN ../../work/vim74/Makefile.rej ./Makefile.rej --- ../../work/vim74/Makefile.rej 1970-01-01 03:00:00.000000000 +0300 +++ ./Makefile.rej 2014-02-22 19:30:45.000000000 +0300 @@ -0,0 +1,18 @@ +*************** +*** 30,36 **** + test84.out test85.out test86.out test87.out test88.out \ + test89.out test90.out test91.out test92.out test93.out \ + test94.out test95.out test96.out test97.out test98.out \ +! test99.out test100.out test101.out test102.out test103.out + + SCRIPTS_GUI = test16.out + +--- 30,37 ---- + test84.out test85.out test86.out test87.out test88.out \ + test89.out test90.out test91.out test92.out test93.out \ + test94.out test95.out test96.out test97.out test98.out \ +! test99.out test100.out test101.out test102.out test103.out \ +! test104.out + + SCRIPTS_GUI = test16.out + diff -ubBwrN ../../work/vim74/Test104.vim ./Test104.vim --- ../../work/vim74/Test104.vim 1970-01-01 03:00:00.000000000 +0300 +++ ./Test104.vim 2014-02-22 19:30:45.000000000 +0300 @@ -0,0 +1 @@ +let Test104#numvar = 123 diff -ubBwrN ../../work/vim74/configure.rej ./configure.rej --- ../../work/vim74/configure.rej 1970-01-01 03:00:00.000000000 +0300 +++ ./configure.rej 2014-02-22 19:30:43.000000000 +0300 @@ -0,0 +1,17 @@ +*************** +*** 4743,4749 **** + if test "${vi_cv_version_luajit+set}" = set; then : + $as_echo_n "(cached) " >&6 + else +! vi_cv_version_luajit=`${vi_cv_path_luajit} -v 2>&1 | sed 's/LuaJIT \([0-9.]*\)\.[0-9]\(-[a-z0-9]\+\)\? .*/\1/'` + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $vi_cv_version_luajit" >&5 + $as_echo "$vi_cv_version_luajit" >&6; } +--- 4743,4749 ---- + if test "${vi_cv_version_luajit+set}" = set; then : + $as_echo_n "(cached) " >&6 + else +! vi_cv_version_luajit=`${vi_cv_path_luajit} -v 2>&1 | sed 's/LuaJIT \([0-9.]*\)\.[0-9]\(-[a-z0-9]*\)* .*/\1/'` + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $vi_cv_version_luajit" >&5 + $as_echo "$vi_cv_version_luajit" >&6; } diff -ubBwrN ../../work/vim74/footest.vim ./footest.vim --- ../../work/vim74/footest.vim 1970-01-01 03:00:00.000000000 +0300 +++ ./footest.vim 2014-02-22 19:30:44.000000000 +0300 @@ -0,0 +1,5 @@ +" Autoload script used by test55 and test60 +let footest#x = 1 +func footest#F() + return 0 +endfunc diff -ubBwrN ../../work/vim74/patch-X ./patch-X --- ../../work/vim74/patch-X 1970-01-01 03:00:00.000000000 +0300 +++ ./patch-X 2014-02-22 19:33:55.000000000 +0300 @@ -0,0 +1,68 @@ +diff -ubBwrN ../../work/vim74/Filelist ./Filelist +--- ../../work/vim74/Filelist 2013-07-13 16:23:38.000000000 +0300 ++++ ./Filelist 2014-02-22 19:30:45.000000000 +0300 +@@ -80,6 +80,7 @@ + src/main.aap \ + src/testdir/main.aap \ + src/testdir/*.in \ ++ src/testdir/sautest/autoload/*.vim \ + src/testdir/test[0-9]*.ok \ + src/testdir/test49.vim \ + src/testdir/test60.vim \ +diff -ubBwrN ../../work/vim74/Makefile.rej ./Makefile.rej +--- ../../work/vim74/Makefile.rej 1970-01-01 03:00:00.000000000 +0300 ++++ ./Makefile.rej 2014-02-22 19:30:45.000000000 +0300 +@@ -0,0 +1,18 @@ ++*************** ++*** 30,36 **** ++ test84.out test85.out test86.out test87.out test88.out \ ++ test89.out test90.out test91.out test92.out test93.out \ ++ test94.out test95.out test96.out test97.out test98.out \ ++! test99.out test100.out test101.out test102.out test103.out ++ ++ SCRIPTS_GUI = test16.out ++ ++--- 30,37 ---- ++ test84.out test85.out test86.out test87.out test88.out \ ++ test89.out test90.out test91.out test92.out test93.out \ ++ test94.out test95.out test96.out test97.out test98.out \ ++! test99.out test100.out test101.out test102.out test103.out \ ++! test104.out ++ ++ SCRIPTS_GUI = test16.out ++ +diff -ubBwrN ../../work/vim74/Test104.vim ./Test104.vim +--- ../../work/vim74/Test104.vim 1970-01-01 03:00:00.000000000 +0300 ++++ ./Test104.vim 2014-02-22 19:30:45.000000000 +0300 +@@ -0,0 +1 @@ ++let Test104#numvar = 123 +diff -ubBwrN ../../work/vim74/configure.rej ./configure.rej +--- ../../work/vim74/configure.rej 1970-01-01 03:00:00.000000000 +0300 ++++ ./configure.rej 2014-02-22 19:30:43.000000000 +0300 +@@ -0,0 +1,17 @@ ++*************** ++*** 4743,4749 **** ++ if test "${vi_cv_version_luajit+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++ else ++! vi_cv_version_luajit=`${vi_cv_path_luajit} -v 2>&1 | sed 's/LuaJIT \([0-9.]*\)\.[0-9]\(-[a-z0-9]\+\)\? .*/\1/'` ++ fi ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $vi_cv_version_luajit" >&5 ++ $as_echo "$vi_cv_version_luajit" >&6; } ++--- 4743,4749 ---- ++ if test "${vi_cv_version_luajit+set}" = set; then : ++ $as_echo_n "(cached) " >&6 ++ else ++! vi_cv_version_luajit=`${vi_cv_path_luajit} -v 2>&1 | sed 's/LuaJIT \([0-9.]*\)\.[0-9]\(-[a-z0-9]*\)* .*/\1/'` ++ fi ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $vi_cv_version_luajit" >&5 ++ $as_echo "$vi_cv_version_luajit" >&6; } +diff -ubBwrN ../../work/vim74/footest.vim ./footest.vim +--- ../../work/vim74/footest.vim 1970-01-01 03:00:00.000000000 +0300 ++++ ./footest.vim 2014-02-22 19:30:44.000000000 +0300 +@@ -0,0 +1,5 @@ ++" Autoload script used by test55 and test60 ++let footest#x = 1 ++func footest#F() ++ return 0 ++endfunc diff -ubBwrN ../../work/vim74/runtime/doc/autocmd.txt ./runtime/doc/autocmd.txt --- ../../work/vim74/runtime/doc/autocmd.txt 2013-08-10 14:24:52.000000000 +0300 +++ ./runtime/doc/autocmd.txt 2014-02-22 19:30:43.000000000 +0300 @@ -480,6 +480,12 @@ |cmdwin-char| *ColorScheme* ColorScheme After loading a color scheme. |:colorscheme| + The pattern is matched against the + colorscheme name. can be used for the + name of the actual file where this option was + set, and for the new colorscheme + name. + *CompleteDone* CompleteDone After Insert mode completion is done. Either diff -ubBwrN ../../work/vim74/runtime/doc/change.txt ./runtime/doc/change.txt --- ../../work/vim74/runtime/doc/change.txt 2013-08-10 14:24:52.000000000 +0300 +++ ./runtime/doc/change.txt 2014-02-22 19:30:40.000000000 +0300 @@ -1069,6 +1069,11 @@ replace and use "0p . You can repeat this as many times as you like, the unnamed register will be changed each time. +When you use a blockwise Visual mode command and yank only a single line into +a register, a paste on a visual selected area will paste that single line on +each of the selected lines (thus replacing the blockwise selected region by a +block of the pasted line). + *blockwise-register* If you use a blockwise Visual mode command to get the text into the register, the block of text will be inserted before ("P") or after ("p") the cursor diff -ubBwrN ../../work/vim74/runtime/doc/cmdline.txt ./runtime/doc/cmdline.txt --- ../../work/vim74/runtime/doc/cmdline.txt 2013-08-10 14:24:52.000000000 +0300 +++ ./runtime/doc/cmdline.txt 2014-02-22 19:30:42.000000000 +0300 @@ -356,6 +356,10 @@ List the recent five entries from all histories: > :history all -5, +:keepp[atterns] {command} *:keepp* *:keeppatterns* + Execute {command}, without adding anything to the search + history + ============================================================================== 2. Command-line completion *cmdline-completion* diff -ubBwrN ../../work/vim74/runtime/doc/eval.txt ./runtime/doc/eval.txt --- ../../work/vim74/runtime/doc/eval.txt 2013-08-10 14:24:53.000000000 +0300 +++ ./runtime/doc/eval.txt 2014-02-22 19:30:44.000000000 +0300 @@ -1454,6 +1454,13 @@ v:foldstart Used for 'foldtext': first line of closed fold. Read-only in the |sandbox|. |fold-foldtext| + *v:hlsearch* *hlsearch-variable* +v:hlsearch Variable that determines whether search highlighting is on. + Makes sense only if 'hlsearch' is enabled which requires + |+extra_search|. Setting this variable to zero acts the like + |:nohlsearch| command, setting it to one acts like > + let &hlsearch = &hlsearch +< *v:insertmode* *insertmode-variable* v:insertmode Used for the |InsertEnter| and |InsertChange| autocommand events. Values: @@ -1712,6 +1719,7 @@ bufwinnr( {expr}) Number window number of buffer {expr} byte2line( {byte}) Number line number at byte count {byte} byteidx( {expr}, {nr}) Number byte index of {nr}'th char in {expr} +byteidxcomp( {expr}, {nr}) Number byte index of {nr}'th char in {expr} call( {func}, {arglist} [, {dict}]) any call {func} with arguments {arglist} ceil( {expr}) Float round {expr} up @@ -2260,7 +2268,10 @@ {expr}. Use zero for the first character, it returns zero. This function is only useful when there are multibyte characters, otherwise the returned value is equal to {nr}. - Composing characters are counted as a separate character. + Composing characters are not counted separately, their byte + length is added to the preceding base character. See + |byteidxcomp()| below for counting composing characters + separately. Example : > echo matchstr(str, ".", byteidx(str, 3)) < will display the fourth character. Another way to do the @@ -2269,7 +2280,20 @@ echo strpart(s, 0, byteidx(s, 1)) < If there are less than {nr} characters -1 is returned. If there are exactly {nr} characters the length of the string - is returned. + in bytes is returned. + +byteidxcomp({expr}, {nr}) *byteidxcomp()* + Like byteidx(), except that a composing character is counted + as a separate character. Example: > + let s = 'e' . nr2char(0x301) + echo byteidx(s, 1) + echo byteidxcomp(s, 1) + echo byteidxcomp(s, 2) +< The first and third echo result in 3 ('e' plus composing + character is 3 bytes), the second echo results in 1 ('e' is + one byte). + Only works different from byteidx() when 'encoding' is set to + a Unicode encoding. call({func}, {arglist} [, {dict}]) *call()* *E699* Call function {func} with the items in |List| {arglist} as @@ -3435,7 +3459,7 @@ "v" for |characterwise| text "V" for |linewise| text "{width}" for |blockwise-visual| text - 0 for an empty or unknown register + "" for an empty or unknown register is one character with value 0x16. If {regname} is not specified, |v:register| is used. diff -ubBwrN ../../work/vim74/runtime/doc/indent.txt ./runtime/doc/indent.txt --- ../../work/vim74/runtime/doc/indent.txt 2013-08-10 14:24:56.000000000 +0300 +++ ./runtime/doc/indent.txt 2014-02-22 19:30:41.000000000 +0300 @@ -545,10 +545,12 @@ (default 70 lines). *cino-#* - #N When N is non-zero recognize shell/Perl comments, starting with - '#'. Default N is zero: don't recognize '#' comments. Note - that lines starting with # will still be seen as preprocessor - lines. + #N When N is non-zero recognize shell/Perl comments starting with + '#', do not recognize preprocessor lines; allow right-shifting + lines that start with "#". + When N is zero (default): don't recognize '#' comments, do + recognize preprocessor lines; right-shifting lines that start + with "#" does not work. The defaults, spelled out in full, are: @@ -556,7 +558,7 @@ c3,C0,/0,(2s,us,U0,w0,W0,k0,m0,j0,J0,)20,*70,#0 Vim puts a line in column 1 if: -- It starts with '#' (preprocessor directives), if 'cinkeys' contains '#'. +- It starts with '#' (preprocessor directives), if 'cinkeys' contains '#0'. - It starts with a label (a keyword followed by ':', other than "case" and "default") and 'cinoptions' does not contain an 'L' entry with a positive value. @@ -581,8 +583,8 @@ Clojure indentation differs somewhat from traditional Lisps, due in part to the use of square and curly brackets, and otherwise by community convention. -These conventions are not always universally followed, so the Clojure indent -script offers a few configurable options, listed below. +These conventions are not universally followed, so the Clojure indent script +offers a few configurable options, listed below. If the current vim does not include searchpairpos(), the indent script falls back to normal 'lisp' indenting, and the following options are ignored. diff -ubBwrN ../../work/vim74/runtime/doc/options.txt ./runtime/doc/options.txt --- ../../work/vim74/runtime/doc/options.txt 2013-08-10 14:24:57.000000000 +0300 +++ ./runtime/doc/options.txt 2014-02-22 19:30:43.000000000 +0300 @@ -6555,6 +6555,9 @@ region by listing them: "en_us,en_ca" supports both US and Canadian English, but not words specific for Australia, New Zealand or Great Britain. + If the name "cjk" is included East Asian characters are excluded from + spell checking. This is useful when editing text that also has Asian + words. *E757* As a special case the name of a .spl file can be given as-is. The first "_xx" in the name is removed and used as the region name @@ -7594,7 +7597,7 @@ *'undolevels'* *'ul'* 'undolevels' 'ul' number (default 100, 1000 for Unix, VMS, Win32 and OS/2) - global + global or local to buffer |global-local| {not in Vi} Maximum number of changes that can be undone. Since undo information is kept in memory, higher numbers will cause more memory to be used @@ -7605,8 +7608,9 @@ < But you can also get Vi compatibility by including the 'u' flag in 'cpoptions', and still be able to use CTRL-R to repeat undo. Also see |undo-two-ways|. - Set to a negative number for no undo at all: > - set ul=-1 + Set to -1 for no undo at all. You might want to do this only for the + current buffer: > + setlocal ul=-1 < This helps when you run out of memory for a single change. Also see |clear-undo|. diff -ubBwrN ../../work/vim74/runtime/doc/spell.txt ./runtime/doc/spell.txt --- ../../work/vim74/runtime/doc/spell.txt 2013-08-10 14:25:01.000000000 +0300 +++ ./runtime/doc/spell.txt 2014-02-22 19:30:43.000000000 +0300 @@ -269,6 +269,13 @@ latin1 yi transliterated Yiddish utf-8 yi-tr transliterated Yiddish + *spell-cjk* +Chinese, Japanese and other East Asian characters are normally marked as +errors, because spell checking of these characters is not supported. If +'spelllang' includes "cjk", these characters are not marked as errors. This +is useful when editing text with spell checking while some Asian words are +present. + SPELL FILES *spell-load* diff -ubBwrN ../../work/vim74/runtime/vimrc_example.vim ./runtime/vimrc_example.vim --- ../../work/vim74/runtime/vimrc_example.vim 2011-04-15 21:58:36.000000000 +0300 +++ ./runtime/vimrc_example.vim 2014-02-22 19:30:45.000000000 +0300 @@ -1,7 +1,7 @@ " An example for a vimrc file. " " Maintainer: Bram Moolenaar -" Last change: 2011 Apr 15 +" Last change: 2014 Feb 05 " " To use it, copy it to " for Unix and OS/2: ~/.vimrc @@ -24,7 +24,8 @@ if has("vms") set nobackup " do not keep a backup file, use versions instead else - set backup " keep a backup file + set backup " keep a backup file (restore to previous version) + set undofile " keep an undo file (undo changes after closing) endif set history=50 " keep 50 lines of command line history set ruler " show the cursor position all the time diff -ubBwrN ../../work/vim74/src/GvimExt/Make_cyg.mak ./src/GvimExt/Make_cyg.mak --- ../../work/vim74/src/GvimExt/Make_cyg.mak 2011-09-30 17:45:49.000000000 +0300 +++ ./src/GvimExt/Make_cyg.mak 2014-02-22 19:30:40.000000000 +0300 @@ -31,12 +31,12 @@ ifeq ($(CROSS),yes) DEL = rm ifeq ($(MINGWOLD),yes) -CXXFLAGS := -O2 -mno-cygwin -fvtable-thunks +CXXFLAGS := -O2 -fvtable-thunks else -CXXFLAGS := -O2 -mno-cygwin +CXXFLAGS := -O2 endif else -CXXFLAGS := -O2 -mno-cygwin +CXXFLAGS := -O2 ifneq (sh.exe, $(SHELL)) DEL = rm else diff -ubBwrN ../../work/vim74/src/Make_bc5.mak ./src/Make_bc5.mak --- ../../work/vim74/src/Make_bc5.mak 2013-06-03 21:09:58.000000000 +0300 +++ ./src/Make_bc5.mak 2014-02-22 19:30:44.000000000 +0300 @@ -419,7 +419,7 @@ ALIGNARG = -a$(ALIGN) # !if ("$(DEBUG)"=="yes") -DEFINES=$(DEFINES) -DDEBUG +DEFINES=$(DEFINES) -DDEBUG -D_DEBUG !endif # !if ("$(OLE)"=="yes") diff -ubBwrN ../../work/vim74/src/Make_cyg.mak ./src/Make_cyg.mak --- ../../work/vim74/src/Make_cyg.mak 2013-07-06 14:32:11.000000000 +0300 +++ ./src/Make_cyg.mak 2014-02-22 19:30:44.000000000 +0300 @@ -1,6 +1,6 @@ # # Makefile for VIM on Win32, using Cygnus gcc -# Last updated by Dan Sharp. Last Change: 2013 Apr 22 +# Last updated by Dan Sharp. Last Change: 2013 Dec 11 # # Also read INSTALLpc.txt! # @@ -155,7 +155,7 @@ ifeq (yes, $(DYNAMIC_PERL)) DEFINES += -DDYNAMIC_PERL -DDYNAMIC_PERL_DLL=\"perl$(PERL_VER).dll\" else -EXTRA_LIBS += $(PERL)/lib/CORE/perl$(PERL_VER).lib +EXTRA_LIBS += -L$(PERL)/lib/CORE -lperl$(PERL_VER) endif endif @@ -272,7 +272,7 @@ DEFINES += -DDYNAMIC_RUBY -DDYNAMIC_RUBY_DLL=\"$(RUBY_INSTALL_NAME).dll\" DEFINES += -DDYNAMIC_RUBY_VER=$(RUBY_VER) else -EXTRA_LIBS += $(RUBY)/lib/$(RUBY_INSTALL_NAME).lib +EXTRA_LIBS += $(RUBY)/lib/$(RUBY_INSTALL_NAME) endif endif @@ -439,8 +439,6 @@ ############################## ifeq (yes, $(USEDLL)) DEFINES += -D_MAX_PATH=256 -D__CYGWIN__ -else -INCLUDES += -mno-cygwin endif ############################## diff -ubBwrN ../../work/vim74/src/Make_ming.mak ./src/Make_ming.mak --- ../../work/vim74/src/Make_ming.mak 2013-07-06 14:32:11.000000000 +0300 +++ ./src/Make_ming.mak 2014-02-22 19:30:44.000000000 +0300 @@ -359,6 +359,7 @@ CFLAGS = -Iproto $(DEFINES) -pipe -w -march=$(ARCH) -Wall WINDRES_FLAGS = --preprocessor="$(WINDRES_CC) -E -xc" -DRC_INVOKED +EXTRA_LIBS = ifdef GETTEXT DEFINES += -DHAVE_GETTEXT -DHAVE_LOCALE_H @@ -377,9 +378,10 @@ endif ifdef PERL -CFLAGS += -I$(PERLLIBS) -DFEAT_PERL -L$(PERLLIBS) +CFLAGS += -I$(PERLLIBS) -DFEAT_PERL ifeq (yes, $(DYNAMIC_PERL)) CFLAGS += -DDYNAMIC_PERL -DDYNAMIC_PERL_DLL=\"perl$(PERL_VER).dll\" +EXTRA_LIBS += -L$(PERLLIBS) -lperl$(PERL_VER) endif endif @@ -632,7 +634,7 @@ ifdef PERL ifeq (no, $(DYNAMIC_PERL)) -LIB += -lperl$(PERL_VER) +LIB += -L$(PERLLIBS) -lperl$(PERL_VER) endif endif diff -ubBwrN ../../work/vim74/src/Make_mvc.mak ./src/Make_mvc.mak --- ../../work/vim74/src/Make_mvc.mak 2013-07-09 14:13:12.000000000 +0300 +++ ./src/Make_mvc.mak 2014-02-22 19:30:46.000000000 +0300 @@ -424,6 +424,12 @@ !if "$(_NMAKE_VER)" == "11.00.60610.1" MSVCVER = 11.0 !endif +!if "$(_NMAKE_VER)" == "11.00.61030.0" +MSVCVER = 11.0 +!endif +!if "$(_NMAKE_VER)" == "12.00.21005.1" +MSVCVER = 12.0 +!endif !endif # Abort building VIM if version of VC is unrecognised. @@ -438,7 +444,7 @@ !endif # Convert processor ID to MVC-compatible number -!if ("$(MSVCVER)" != "8.0") && ("$(MSVCVER)" != "9.0") && ("$(MSVCVER)" != "10.0") && ("$(MSVCVER)" != "11.0") +!if ("$(MSVCVER)" != "8.0") && ("$(MSVCVER)" != "9.0") && ("$(MSVCVER)" != "10.0") && ("$(MSVCVER)" != "11.0") && ("$(MSVCVER)" != "12.0") !if "$(CPUNR)" == "i386" CPUARG = /G3 !elseif "$(CPUNR)" == "i486" @@ -472,7 +478,7 @@ OPTFLAG = /Ox !endif -!if ("$(MSVCVER)" == "8.0") || ("$(MSVCVER)" == "9.0") || ("$(MSVCVER)" == "10.0") || ("$(MSVCVER)" == "11.0") +!if ("$(MSVCVER)" == "8.0") || ("$(MSVCVER)" == "9.0") || ("$(MSVCVER)" == "10.0") || ("$(MSVCVER)" == "11.0") || ("$(MSVCVER)" == "12.0") # Use link time code generation if not worried about size !if "$(OPTIMIZE)" != "SPACE" OPTFLAG = $(OPTFLAG) /GL @@ -485,7 +491,7 @@ !endif # Static code analysis generally available starting with VS2012 -!if ("$(ANALYZE)" == "yes") && ("$(MSVCVER)" == "11.0") +!if ("$(ANALYZE)" == "yes") && (("$(MSVCVER)" == "10.0") || ("$(MSVCVER)" == "11.0") || ("$(MSVCVER)" == "12.0")) CFLAGS=$(CFLAGS) /analyze !endif @@ -822,7 +828,12 @@ PERL_LIB = $(PERL_INCDIR)\perl.lib !else PERL_DLL = perl$(PERL_VER).dll +!if exist($(PERL_INCDIR)\perl$(PERL_VER).lib) PERL_LIB = $(PERL_INCDIR)\perl$(PERL_VER).lib +!else +# For ActivePerl 5.18 and later +PERL_LIB = $(PERL_INCDIR)\libperl$(PERL_VER).a +!endif !endif CFLAGS = $(CFLAGS) -DFEAT_PERL @@ -943,7 +954,7 @@ # Report link time code generation progress if used. !ifdef NODEBUG -!if ("$(MSVCVER)" == "8.0") || ("$(MSVCVER)" == "9.0") || ("$(MSVCVER)" == "10.0") || ("$(MSVCVER)" == "11.0") +!if ("$(MSVCVER)" == "8.0") || ("$(MSVCVER)" == "9.0") || ("$(MSVCVER)" == "10.0") || ("$(MSVCVER)" == "11.0") || ("$(MSVCVER)" == "12.0") !if "$(OPTIMIZE)" != "SPACE" LINKARGS1 = $(LINKARGS1) /LTCG:STATUS !endif diff -ubBwrN ../../work/vim74/src/Makefile ./src/Makefile --- ../../work/vim74/src/Makefile 2013-08-10 15:21:15.000000000 +0300 +++ ./src/Makefile 2014-02-22 19:28:36.000000000 +0300 @@ -954,7 +954,7 @@ ### Location of Vim files (should not need to be changed, and {{{1 ### some things might not work when they are changed!) VIMDIR = /vim -VIMRTDIR = /vim$(VIMMAJOR)$(VIMMINOR) +VIMRTDIR = HELPSUBDIR = /doc COLSUBDIR = /colors SYNSUBDIR = /syntax @@ -2084,57 +2084,57 @@ # install the language specific files for tools, if they were unpacked install-tool-languages: - -$(SHELL) ./installman.sh xxd $(DEST_MAN_FR) "-fr" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh xxd $(DEST_MAN_FR_I) "-fr" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh xxd $(DEST_MAN_FR_U) "-fr.UTF-8" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh xxd $(DEST_MAN_IT) "-it" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh xxd $(DEST_MAN_IT_I) "-it" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh xxd $(DEST_MAN_IT_U) "-it.UTF-8" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh xxd $(DEST_MAN_JA_U) "-ja.UTF-8" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh xxd $(DEST_MAN_PL) "-pl" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh xxd $(DEST_MAN_PL_I) "-pl" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh xxd $(DEST_MAN_PL_U) "-pl.UTF-8" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh xxd $(DEST_MAN_RU) "-ru" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh xxd $(DEST_MAN_RU_U) "-ru.UTF-8" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh xxd $(DEST_MAN_FR) "-fr" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh xxd $(DEST_MAN_FR_I) "-fr" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh xxd $(DEST_MAN_FR_U) "-fr.UTF-8" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh xxd $(DEST_MAN_IT) "-it" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh xxd $(DEST_MAN_IT_I) "-it" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh xxd $(DEST_MAN_IT_U) "-it.UTF-8" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh xxd $(DEST_MAN_JA_U) "-ja.UTF-8" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh xxd $(DEST_MAN_PL) "-pl" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh xxd $(DEST_MAN_PL_I) "-pl" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh xxd $(DEST_MAN_PL_U) "-pl.UTF-8" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh xxd $(DEST_MAN_RU) "-ru" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh xxd $(DEST_MAN_RU_U) "-ru.UTF-8" $(INSTALLMANARGS) # install the language specific files, if they were unpacked install-languages: languages $(DEST_LANG) $(DEST_KMAP) - -$(SHELL) ./installman.sh install $(DEST_MAN_FR) "-fr" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh install $(DEST_MAN_FR_I) "-fr" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh install $(DEST_MAN_FR_U) "-fr.UTF-8" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh install $(DEST_MAN_IT) "-it" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh install $(DEST_MAN_IT_I) "-it" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh install $(DEST_MAN_IT_U) "-it.UTF-8" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh install $(DEST_MAN_JA_U) "-ja.UTF-8" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh install $(DEST_MAN_PL) "-pl" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh install $(DEST_MAN_PL_I) "-pl" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh install $(DEST_MAN_PL_U) "-pl.UTF-8" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh install $(DEST_MAN_RU) "-ru" $(INSTALLMANARGS) - -$(SHELL) ./installman.sh install $(DEST_MAN_RU_U) "-ru.UTF-8" $(INSTALLMANARGS) - -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ - $(DEST_MAN_FR) $(INSTALLMLARGS) - -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ - $(DEST_MAN_FR_I) $(INSTALLMLARGS) - -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ - $(DEST_MAN_FR_U) $(INSTALLMLARGS) - -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ - $(DEST_MAN_IT) $(INSTALLMLARGS) - -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ - $(DEST_MAN_IT_I) $(INSTALLMLARGS) - -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ - $(DEST_MAN_IT_U) $(INSTALLMLARGS) - -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ - $(DEST_MAN_JA_U) $(INSTALLMLARGS) - -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ - $(DEST_MAN_PL) $(INSTALLMLARGS) - -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ - $(DEST_MAN_PL_I) $(INSTALLMLARGS) - -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ - $(DEST_MAN_PL_U) $(INSTALLMLARGS) - -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ - $(DEST_MAN_RU) $(INSTALLMLARGS) - -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ - $(DEST_MAN_RU_U) $(INSTALLMLARGS) +# -$(SHELL) ./installman.sh install $(DEST_MAN_FR) "-fr" $(INSTALLMANARGS)# +# -$(SHELL) ./installman.sh install $(DEST_MAN_FR_I) "-fr" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh install $(DEST_MAN_FR_U) "-fr.UTF-8" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh install $(DEST_MAN_IT) "-it" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh install $(DEST_MAN_IT_I) "-it" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh install $(DEST_MAN_IT_U) "-it.UTF-8" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh install $(DEST_MAN_JA_U) "-ja.UTF-8" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh install $(DEST_MAN_PL) "-pl" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh install $(DEST_MAN_PL_I) "-pl" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh install $(DEST_MAN_PL_U) "-pl.UTF-8" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh install $(DEST_MAN_RU) "-ru" $(INSTALLMANARGS) +# -$(SHELL) ./installman.sh install $(DEST_MAN_RU_U) "-ru.UTF-8" $(INSTALLMANARGS) +# -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ +# $(DEST_MAN_FR) $(INSTALLMLARGS) +# -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ +# $(DEST_MAN_FR_I) $(INSTALLMLARGS) +# -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ +# $(DEST_MAN_FR_U) $(INSTALLMLARGS) +# -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ +# $(DEST_MAN_IT) $(INSTALLMLARGS) +# -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ +# $(DEST_MAN_IT_I) $(INSTALLMLARGS) +# -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ +# $(DEST_MAN_IT_U) $(INSTALLMLARGS) +# -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ +# $(DEST_MAN_JA_U) $(INSTALLMLARGS) +# -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ +# $(DEST_MAN_PL) $(INSTALLMLARGS) +# -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ +# $(DEST_MAN_PL_I) $(INSTALLMLARGS) +# -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ +# $(DEST_MAN_PL_U) $(INSTALLMLARGS) +# -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ +# $(DEST_MAN_RU) $(INSTALLMLARGS) +# -$(SHELL) ./installml.sh install "$(GUI_MAN_TARGETS)" \ +# $(DEST_MAN_RU_U) $(INSTALLMLARGS) if test -n "$(MAKEMO)" -a -f $(PODIR)/Makefile; then \ cd $(PODIR); $(MAKE) prefix=$(DESTDIR)$(prefix) LOCALEDIR=$(DEST_LANG) \ INSTALL_DATA=$(INSTALL_DATA) FILEMOD=$(FILEMOD) install; \ @@ -2154,18 +2154,18 @@ ICON16PATH = $(DESTDIR)$(DATADIR)/icons/locolor/16x16/apps KDEPATH = $(HOME)/.kde/share/icons install-icons: - if test -d $(ICON48PATH) -a -w $(ICON48PATH) \ - -a ! -f $(ICON48PATH)/gvim.png; then \ - $(INSTALL_DATA) $(SCRIPTSOURCE)/vim48x48.png $(ICON48PATH)/gvim.png; \ - fi - if test -d $(ICON32PATH) -a -w $(ICON32PATH) \ - -a ! -f $(ICON32PATH)/gvim.png; then \ - $(INSTALL_DATA) $(SCRIPTSOURCE)/vim32x32.png $(ICON32PATH)/gvim.png; \ - fi - if test -d $(ICON16PATH) -a -w $(ICON16PATH) \ - -a ! -f $(ICON16PATH)/gvim.png; then \ - $(INSTALL_DATA) $(SCRIPTSOURCE)/vim16x16.png $(ICON16PATH)/gvim.png; \ - fi +# if test -d $(ICON48PATH) -a -w $(ICON48PATH) \ +# -a ! -f $(ICON48PATH)/gvim.png; then \ +# $(INSTALL_DATA) $(SCRIPTSOURCE)/vim48x48.png $(ICON48PATH)/gvim.png; \ +# fi +# if test -d $(ICON32PATH) -a -w $(ICON32PATH) \ +# -a ! -f $(ICON32PATH)/gvim.png; then \ +# $(INSTALL_DATA) $(SCRIPTSOURCE)/vim32x32.png $(ICON32PATH)/gvim.png; \ +# fi +# if test -d $(ICON16PATH) -a -w $(ICON16PATH) \ +# -a ! -f $(ICON16PATH)/gvim.png; then \ +# $(INSTALL_DATA) $(SCRIPTSOURCE)/vim16x16.png $(ICON16PATH)/gvim.png; \ +# fi $(HELPSOURCE)/vim.1 $(MACROSOURCE) $(TOOLSSOURCE): diff -ubBwrN ../../work/vim74/src/blowfish.c ./src/blowfish.c --- ../../work/vim74/src/blowfish.c 2010-12-17 20:58:18.000000000 +0200 +++ ./src/blowfish.c 2014-02-22 19:30:45.000000000 +0300 @@ -6,7 +6,7 @@ * Do ":help credits" in Vim to see a list of people who contributed. * See README.txt for an overview of the Vim source code. * - * Blowfish encryption for Vim; in Blowfish output feedback mode. + * Blowfish encryption for Vim; in Blowfish cipher feedback mode. * Contributed by Mohsin Ahmed, http://www.cs.albany.edu/~mosh * Based on http://www.schneier.com/blowfish.html by Bruce Schneier. */ @@ -19,7 +19,7 @@ #define BF_BLOCK 8 #define BF_BLOCK_MASK 7 -#define BF_OFB_LEN (8*(BF_BLOCK)) +#define BF_CFB_LEN (8*(BF_BLOCK)) typedef union { UINT32_T ul[2]; @@ -554,42 +554,42 @@ return err > 0 ? FAIL : OK; } -/* Output feedback mode. */ +/* Cipher feedback mode. */ static int randbyte_offset = 0; static int update_offset = 0; -static char_u ofb_buffer[BF_OFB_LEN]; /* 64 bytes */ +static char_u cfb_buffer[BF_CFB_LEN]; /* 64 bytes */ /* * Initialize with seed "iv[iv_len]". */ void -bf_ofb_init(iv, iv_len) +bf_cfb_init(iv, iv_len) char_u *iv; int iv_len; { int i, mi; randbyte_offset = update_offset = 0; - vim_memset(ofb_buffer, 0, BF_OFB_LEN); + vim_memset(cfb_buffer, 0, BF_CFB_LEN); if (iv_len > 0) { - mi = iv_len > BF_OFB_LEN ? iv_len : BF_OFB_LEN; + mi = iv_len > BF_CFB_LEN ? iv_len : BF_CFB_LEN; for (i = 0; i < mi; i++) - ofb_buffer[i % BF_OFB_LEN] ^= iv[i % iv_len]; + cfb_buffer[i % BF_CFB_LEN] ^= iv[i % iv_len]; } } -#define BF_OFB_UPDATE(c) { \ - ofb_buffer[update_offset] ^= (char_u)c; \ - if (++update_offset == BF_OFB_LEN) \ +#define BF_CFB_UPDATE(c) { \ + cfb_buffer[update_offset] ^= (char_u)c; \ + if (++update_offset == BF_CFB_LEN) \ update_offset = 0; \ } #define BF_RANBYTE(t) { \ if ((randbyte_offset & BF_BLOCK_MASK) == 0) \ - bf_e_cblock(&ofb_buffer[randbyte_offset]); \ - t = ofb_buffer[randbyte_offset]; \ - if (++randbyte_offset == BF_OFB_LEN) \ + bf_e_cblock(&cfb_buffer[randbyte_offset]); \ + t = cfb_buffer[randbyte_offset]; \ + if (++randbyte_offset == BF_CFB_LEN) \ randbyte_offset = 0; \ } @@ -610,7 +610,7 @@ { ztemp = from[i]; BF_RANBYTE(t); - BF_OFB_UPDATE(ztemp); + BF_CFB_UPDATE(ztemp); to[i] = t ^ ztemp; } } @@ -630,7 +630,7 @@ { BF_RANBYTE(t); *p ^= t; - BF_OFB_UPDATE(*p); + BF_CFB_UPDATE(*p); } } @@ -646,13 +646,13 @@ for (p = passwd; *p != NUL; ++p) { - BF_OFB_UPDATE(*p); + BF_CFB_UPDATE(*p); } } static int save_randbyte_offset; static int save_update_offset; -static char_u save_ofb_buffer[BF_OFB_LEN]; +static char_u save_cfb_buffer[BF_CFB_LEN]; static UINT32_T save_pax[18]; static UINT32_T save_sbx[4][256]; @@ -665,7 +665,7 @@ { save_randbyte_offset = randbyte_offset; save_update_offset = update_offset; - mch_memmove(save_ofb_buffer, ofb_buffer, BF_OFB_LEN); + mch_memmove(save_cfb_buffer, cfb_buffer, BF_CFB_LEN); mch_memmove(save_pax, pax, 4 * 18); mch_memmove(save_sbx, sbx, 4 * 4 * 256); } @@ -679,7 +679,7 @@ { randbyte_offset = save_randbyte_offset; update_offset = save_update_offset; - mch_memmove(ofb_buffer, save_ofb_buffer, BF_OFB_LEN); + mch_memmove(cfb_buffer, save_cfb_buffer, BF_CFB_LEN); mch_memmove(pax, save_pax, 4 * 18); mch_memmove(sbx, save_sbx, 4 * 4 * 256); } diff -ubBwrN ../../work/vim74/src/buffer.c ./src/buffer.c --- ../../work/vim74/src/buffer.c 2013-07-17 17:39:00.000000000 +0300 +++ ./src/buffer.c 2014-02-22 19:30:44.000000000 +0300 @@ -211,7 +211,12 @@ /* if first time loading this buffer, init b_chartab[] */ if (curbuf->b_flags & BF_NEVERLOADED) + { (void)buf_init_chartab(curbuf, FALSE); +#ifdef FEAT_CINDENT + parse_cino(curbuf); +#endif + } /* * Set/reset the Changed flag first, autocmds may change the buffer. @@ -989,6 +994,50 @@ #if defined(FEAT_LISTCMDS) || defined(FEAT_PYTHON) \ || defined(FEAT_PYTHON3) || defined(PROTO) +static int empty_curbuf __ARGS((int close_others, int forceit, int action)); + +/* + * Make the current buffer empty. + * Used when it is wiped out and it's the last buffer. + */ + static int +empty_curbuf(close_others, forceit, action) + int close_others; + int forceit; + int action; +{ + int retval; + buf_T *buf = curbuf; + + if (action == DOBUF_UNLOAD) + { + EMSG(_("E90: Cannot unload last buffer")); + return FAIL; + } + + if (close_others) + { + /* Close any other windows on this buffer, then make it empty. */ +#ifdef FEAT_WINDOWS + close_windows(buf, TRUE); +#endif + } + + setpcmark(); + retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, + forceit ? ECMD_FORCEIT : 0, curwin); + + /* + * do_ecmd() may create a new buffer, then we have to delete + * the old one. But do_ecmd() may have done that already, check + * if the buffer still exists. + */ + if (buf != curbuf && buf_valid(buf) && buf->b_nwindows == 0) + close_buffer(NULL, buf, action, FALSE); + if (!close_others) + need_fileinfo = FALSE; + return retval; +} /* * Implementation of the commands for the buffer list. * @@ -1109,7 +1158,6 @@ if (unload) { int forward; - int retval; /* When unloading or deleting a buffer that's already unloaded and * unlisted: fail silently. */ @@ -1150,30 +1198,7 @@ if (bp->b_p_bl && bp != buf) break; if (bp == NULL && buf == curbuf) - { - if (action == DOBUF_UNLOAD) - { - EMSG(_("E90: Cannot unload last buffer")); - return FAIL; - } - - /* Close any other windows on this buffer, then make it empty. */ -#ifdef FEAT_WINDOWS - close_windows(buf, TRUE); -#endif - setpcmark(); - retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, - forceit ? ECMD_FORCEIT : 0, curwin); - - /* - * do_ecmd() may create a new buffer, then we have to delete - * the old one. But do_ecmd() may have done that already, check - * if the buffer still exists. - */ - if (buf != curbuf && buf_valid(buf) && buf->b_nwindows == 0) - close_buffer(NULL, buf, action, FALSE); - return retval; - } + return empty_curbuf(TRUE, forceit, action); #ifdef FEAT_WINDOWS /* @@ -1186,7 +1211,10 @@ && !(curwin->w_closing || curwin->w_buffer->b_closing) # endif && (firstwin != lastwin || first_tabpage->tp_next != NULL)) - win_close(curwin, FALSE); + { + if (win_close(curwin, FALSE) == FAIL) + break; + } #endif /* @@ -1204,7 +1232,8 @@ /* * Deleting the current buffer: Need to find another buffer to go to. - * There must be another, otherwise it would have been handled above. + * There should be another, otherwise it would have been handled + * above. However, autocommands may have deleted all buffers. * First use au_new_curbuf, if it is valid. * Then prefer the buffer we most recently visited. * Else try to find one that is loaded, after the current buffer, @@ -1303,6 +1332,13 @@ } } + if (buf == NULL) + { + /* Autocommands must have wiped out all other buffers. Only option + * now is to make the current buffer empty. */ + return empty_curbuf(FALSE, forceit, action); + } + /* * make buf current buffer */ @@ -1941,6 +1977,7 @@ clear_string_option(&buf->b_p_qe); #endif buf->b_p_ar = -1; + buf->b_p_ul = NO_LOCAL_UNDOLEVEL; } /* @@ -4059,6 +4096,7 @@ item[curitem].minwid = -syn_namen2id(t, (int)(s - t)); curitem++; } + if (*s != NUL) ++s; continue; } diff -ubBwrN ../../work/vim74/src/config.h.in ./src/config.h.in --- ../../work/vim74/src/config.h.in 2013-02-26 16:18:19.000000000 +0300 +++ ./src/config.h.in 2014-02-22 19:30:41.000000000 +0300 @@ -442,3 +442,6 @@ /* Define if you want Cygwin to use the WIN32 clipboard, not compatible with X11*/ #undef FEAT_CYGWIN_WIN32_CLIPBOARD + +/* Define if we have AvailabilityMacros.h on Mac OS X */ +#undef HAVE_AVAILABILITYMACROS_H diff -ubBwrN ../../work/vim74/src/configure.in ./src/configure.in --- ../../work/vim74/src/configure.in 2013-08-04 21:00:50.000000000 +0300 +++ ./src/configure.in 2014-02-22 19:30:46.000000000 +0300 @@ -62,6 +62,29 @@ 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 @@ -181,7 +204,8 @@ OS_EXTRA_SRC="os_macosx.m os_mac_conv.c"; OS_EXTRA_OBJ="objects/os_macosx.o objects/os_mac_conv.o" dnl TODO: use -arch i386 on Intel machines - CPPFLAGS="$CPPFLAGS -DMACOS_X_UNIX -no-cpp-precomp" + dnl Removed -no-cpp-precomp, only for very old compilers. + CPPFLAGS="$CPPFLAGS -DMACOS_X_UNIX" dnl If Carbon is found, assume we don't want X11 dnl unless it was specifically asked for (--with-x) @@ -205,6 +229,10 @@ AC_MSG_RESULT(no) fi +dnl Mac OS X 10.9+ no longer include AvailabilityMacros.h in Carbon +dnl so we need to include it to have access to version macros. +AC_CHECK_HEADERS(AvailabilityMacros.h) + AC_SUBST(OS_EXTRA_SRC) AC_SUBST(OS_EXTRA_OBJ) @@ -235,8 +263,8 @@ ]) if test "$GCC" = yes -a "$local_dir" != no; then echo 'void f(){}' > conftest.c - dnl -no-cpp-precomp is needed for OS X 10.2 (Ben Fowler) - have_local_include=`${CC-cc} -no-cpp-precomp -c -v conftest.c 2>&1 | grep "${local_dir}/include"` + dnl Removed -no-cpp-precomp, only needed for OS X 10.2 (Ben Fowler) + have_local_include=`${CC-cc} -c -v conftest.c 2>&1 | grep "${local_dir}/include"` have_local_lib=`${CC-cc} -c -v conftest.c 2>&1 | grep "${local_dir}/lib"` rm -f conftest.c conftest.o fi @@ -468,7 +496,7 @@ if test "X$vi_cv_path_luajit" != "X"; then dnl -- find LuaJIT version AC_CACHE_CHECK(LuaJIT version, vi_cv_version_luajit, - [ vi_cv_version_luajit=`${vi_cv_path_luajit} -v | sed 's/LuaJIT \([[0-9.]]*\)\.[[0-9]] .*/\1/'` ]) + [ vi_cv_version_luajit=`${vi_cv_path_luajit} -v 2>&1 | sed 's/LuaJIT \([[0-9.]]*\)\.[[0-9]]\(-[[a-z0-9]]*\)* .*/\1/'` ]) AC_CACHE_CHECK(Lua version of LuaJIT, vi_cv_version_lua_luajit, [ vi_cv_version_lua_luajit=`${vi_cv_path_luajit} -e "print(_VERSION)" | sed 's/.* //'` ]) vi_cv_path_lua="$vi_cv_path_luajit" @@ -774,9 +802,19 @@ AC_MSG_CHECKING(for mzscheme_base.c) if test -f "${SCHEME_COLLECTS}collects/scheme/base.ss" ; then MZSCHEME_EXTRA="mzscheme_base.c" + MZSCHEME_MZC="${vi_cv_path_mzscheme_pfx}/bin/mzc" + MZSCHEME_MOD="++lib scheme/base" else if test -f "${SCHEME_COLLECTS}collects/scheme/base.rkt" ; then MZSCHEME_EXTRA="mzscheme_base.c" + MZSCHEME_MZC="${vi_cv_path_mzscheme_pfx}/bin/mzc" + MZSCHEME_MOD="++lib scheme/base" + else + if test -f "${SCHEME_COLLECTS}collects/racket/base.rkt" ; then + MZSCHEME_EXTRA="mzscheme_base.c" + MZSCHEME_MZC="${vi_cv_path_mzscheme_pfx}/bin/raco ctool" + MZSCHEME_MOD="" + fi fi fi if test "X$MZSCHEME_EXTRA" != "X" ; then @@ -3697,6 +3735,9 @@ fi dnl Check if gettext() is working and if it needs -lintl +dnl We take care to base this on an empty LIBS: on some systems libelf would be +dnl in LIBS and implicitly take along libintl. The final LIBS would then not +dnl contain libintl, and the link step would fail due to -Wl,--as-needed. AC_MSG_CHECKING(--disable-nls argument) AC_ARG_ENABLE(nls, [ --disable-nls Don't support NLS (gettext()).], , @@ -3715,16 +3756,18 @@ if test -f po/Makefile; then have_gettext="no" if test -n "$MSGFMT"; then + olibs=$LIBS + LIBS="" AC_TRY_LINK( [#include ], [gettext("Test");], - AC_MSG_RESULT([gettext() works]); have_gettext="yes", - olibs=$LIBS - LIBS="$LIBS -lintl" + AC_MSG_RESULT([gettext() works]); have_gettext="yes"; LIBS=$olibs, + LIBS="-lintl" AC_TRY_LINK( [#include ], [gettext("Test");], - AC_MSG_RESULT([gettext() works with -lintl]); have_gettext="yes", + AC_MSG_RESULT([gettext() works with -lintl]); have_gettext="yes"; + LIBS="$olibs -lintl", AC_MSG_RESULT([gettext() doesn't work]); LIBS=$olibs)) else diff -ubBwrN ../../work/vim74/src/diff.c ./src/diff.c --- ../../work/vim74/src/diff.c 2013-07-17 14:43:15.000000000 +0300 +++ ./src/diff.c 2014-02-22 19:30:40.000000000 +0300 @@ -1203,7 +1203,7 @@ for (wp = firstwin; wp != NULL; wp = wp->w_next) { - if (wp == curwin || (eap->forceit && wp->w_p_diff)) + if (eap->forceit ? wp->w_p_diff : wp == curwin) { /* Set 'diff', 'scrollbind' off and 'wrap' on. If option values * were saved in diff_win_options() restore them. */ diff -ubBwrN ../../work/vim74/src/dosinst.c ./src/dosinst.c --- ../../work/vim74/src/dosinst.c 2013-05-06 05:06:04.000000000 +0300 +++ ./src/dosinst.c 2014-02-22 19:30:43.000000000 +0300 @@ -1192,23 +1192,29 @@ fprintf(fd, " if arg3 =~ ' ' | let arg3 = '\"' . arg3 . '\"' | endif\n"); /* If the path has a space: When using cmd.exe (Win NT/2000/XP) put - * quotes around the whole command and around the diff command. + * quotes around the diff command and rely on the default value of + * shellxquote to solve the quoting problem for the whole command. + * * Otherwise put a double quote just before the space and at the * end of the command. Putting quotes around the whole thing * doesn't work on Win 95/98/ME. This is mostly guessed! */ - fprintf(fd, " let eq = ''\n"); fprintf(fd, " if $VIMRUNTIME =~ ' '\n"); fprintf(fd, " if &sh =~ '\\ ' . arg3 . eq\n"); - + fprintf(fd, " silent execute '!' . cmd . ' ' . opt . arg1 . ' ' . arg2 . ' > ' . arg3\n"); + fprintf(fd, " if exists('l:shxq_sav')\n"); + fprintf(fd, " let &shellxquote=l:shxq_sav\n"); + fprintf(fd, " endif\n"); fprintf(fd, "endfunction\n"); fprintf(fd, "\n"); } @@ -1773,9 +1779,11 @@ /* * We used to use "homedir" as the working directory, but that is a bad choice - * on multi-user systems. Not specifying a directory appears to work best. + * on multi-user systems. However, not specifying a directory results in the + * current directory to be c:\Windows\system32 on Windows 7. Use environment + * variables instead. */ -#define WORKDIR "" +#define WORKDIR "%HOMEDRIVE%%HOMEPATH%" /* * Create shortcut(s) in the Start Menu\Programs\Vim folder. diff -ubBwrN ../../work/vim74/src/edit.c ./src/edit.c --- ../../work/vim74/src/edit.c 2013-07-04 21:22:25.000000000 +0300 +++ ./src/edit.c 2014-02-22 19:30:45.000000000 +0300 @@ -199,7 +199,7 @@ static void spell_back_to_badword __ARGS((void)); static int spell_bad_len = 0; /* length of located bad word */ #endif -static void stop_insert __ARGS((pos_T *end_insert_pos, int esc)); +static void stop_insert __ARGS((pos_T *end_insert_pos, int esc, int nomove)); static int echeck_abbr __ARGS((int)); static int replace_pop __ARGS((void)); static void replace_join __ARGS((int off)); @@ -1556,8 +1556,9 @@ int conceal_update_lines = FALSE; #endif - if (!char_avail()) - { + if (char_avail()) + return; + #if defined(FEAT_AUTOCMD) || defined(FEAT_CONCEAL) /* Trigger CursorMoved if the cursor moved. Not when the popup menu is * visible, the command might delete it. */ @@ -1601,9 +1602,10 @@ last_cursormoved = curwin->w_cursor; } #endif + #ifdef FEAT_AUTOCMD /* Trigger TextChangedI if b_changedtick differs. */ - if (!ready && has_textchangedI() + if (ready && has_textchangedI() && last_changedtick != curbuf->b_changedtick # ifdef FEAT_INS_EXPAND && !pum_visible() @@ -1637,7 +1640,6 @@ setcursor(); emsg_on_display = FALSE; /* may remove error message now */ } -} /* * Handle a CTRL-V or CTRL-Q typed in Insert mode. @@ -3467,7 +3469,6 @@ } 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(); @@ -4179,6 +4180,7 @@ char_u *dict = NULL; int dict_f = 0; compl_T *old_match; + int set_match_pos; if (!compl_started) { @@ -4197,6 +4199,7 @@ for (;;) { found_new_match = FAIL; + set_match_pos = FALSE; /* For ^N/^P pick a new entry from e_cpt if compl_started is off, * or if found_all says this entry is done. For ^X^L only use the @@ -4216,6 +4219,10 @@ dec(&first_match_pos); last_match_pos = first_match_pos; type = 0; + + /* Remember the first match so that the loop stops when we + * wrap and come back there a second time. */ + set_match_pos = TRUE; } else if (vim_strchr((char_u *)"buwU", *e_cpt) != NULL && (ins_buf = ins_compl_next_buf(ins_buf, *e_cpt)) != curbuf) @@ -4380,7 +4387,7 @@ if (ins_buf->b_p_inf) p_scs = FALSE; - /* buffers other than curbuf are scanned from the beginning or the + /* Buffers other than curbuf are scanned from the beginning or the * end but never from the middle, thus setting nowrapscan in this * buffers is a good idea, on the other hand, we always set * wrapscan for curbuf to avoid missing matches -- Acevedo,Webb */ @@ -4407,12 +4414,13 @@ compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG, RE_LAST, (linenr_T)0, NULL); --msg_silent; - if (!compl_started) + if (!compl_started || set_match_pos) { /* set "compl_started" even on fail */ compl_started = TRUE; first_match_pos = *pos; last_match_pos = *pos; + set_match_pos = FALSE; } else if (first_match_pos.lnum == last_match_pos.lnum && first_match_pos.col == last_match_pos.col) @@ -5184,9 +5192,21 @@ } else if (ctrl_x_mode == CTRL_X_FILES) { - while (--startcol >= 0 && vim_isfilec(line[startcol])) - ; - compl_col += ++startcol; + /* Go back to just before the first filename character. */ + if (startcol > 0) + { + char_u *p = line + startcol; + + mb_ptr_back(line, p); + while (p > line && vim_isfilec(PTR2CHAR(p))) + mb_ptr_back(line, p); + if (p == line && vim_isfilec(PTR2CHAR(p))) + startcol = 0; + else + startcol = (int)(p - line) + 1; + } + + compl_col += startcol; compl_length = (int)curs_col - startcol; compl_pattern = addstar(line + compl_col, compl_length, EXPAND_FILES); @@ -6687,7 +6707,7 @@ if (!arrow_used) /* something has been inserted */ { AppendToRedobuff(ESC_STR); - stop_insert(end_insert_pos, FALSE); + stop_insert(end_insert_pos, FALSE, FALSE); arrow_used = TRUE; /* this means we stopped the current insert */ } #ifdef FEAT_SPELL @@ -6776,9 +6796,10 @@ * to another window/buffer. */ static void -stop_insert(end_insert_pos, esc) +stop_insert(end_insert_pos, esc, nomove) pos_T *end_insert_pos; int esc; /* called by ins_esc() */ + int nomove; /* , don't move cursor */ { int cc; char_u *ptr; @@ -6849,7 +6870,7 @@ * Do this when ESC was used or moving the cursor up/down. * Check for the old position still being valid, just in case the text * got changed unexpectedly. */ - if (did_ai && (esc || (vim_strchr(p_cpo, CPO_INDENT) == NULL + if (!nomove && did_ai && (esc || (vim_strchr(p_cpo, CPO_INDENT) == NULL && curwin->w_cursor.lnum != end_insert_pos->lnum)) && end_insert_pos->lnum <= curbuf->b_ml.ml_line_count) { @@ -7845,8 +7866,7 @@ if (try_match && keytyped == ':') { p = ml_get_curline(); - if (cin_iscase(p, FALSE) || cin_isscopedecl(p) - || cin_islabel(30)) + if (cin_iscase(p, FALSE) || cin_isscopedecl(p) || cin_islabel()) return TRUE; /* Need to get the line again after cin_islabel(). */ p = ml_get_curline(); @@ -7856,7 +7876,7 @@ { p[curwin->w_cursor.col - 1] = ' '; i = (cin_iscase(p, FALSE) || cin_isscopedecl(p) - || cin_islabel(30)); + || cin_islabel()); p = ml_get_curline(); p[curwin->w_cursor.col - 1] = ':'; if (i) @@ -8366,7 +8386,7 @@ disabled_redraw = TRUE; return FALSE; /* repeat the insert */ } - stop_insert(&curwin->w_cursor, TRUE); + stop_insert(&curwin->w_cursor, TRUE, nomove); undisplay_dollar(); } @@ -8946,7 +8966,7 @@ *inserted_space_p = FALSE; if (p_sta && in_indent) - ts = (int)get_sw_value(); + ts = (int)get_sw_value(curbuf); else ts = (int)get_sts_value(); /* Compute the virtual column where we want to be. Since @@ -9635,7 +9655,7 @@ * When nothing special, insert TAB like a normal character */ if (!curbuf->b_p_et - && !(p_sta && ind && curbuf->b_p_ts != get_sw_value()) + && !(p_sta && ind && curbuf->b_p_ts != get_sw_value(curbuf)) && get_sts_value() == 0) return TRUE; @@ -9651,7 +9671,7 @@ AppendToRedobuff((char_u *)"\t"); if (p_sta && ind) /* insert tab in indent, use 'shiftwidth' */ - temp = (int)get_sw_value(); + temp = (int)get_sw_value(curbuf); else if (curbuf->b_p_sts != 0) /* use 'softtabstop' when set */ temp = (int)get_sts_value(); else /* otherwise use 'tabstop' */ diff -ubBwrN ../../work/vim74/src/eval.c ./src/eval.c --- ../../work/vim74/src/eval.c 2013-07-05 19:23:42.000000000 +0300 +++ ./src/eval.c 2014-02-22 19:30:45.000000000 +0300 @@ -125,9 +125,6 @@ */ static hashtab_T compat_hashtab; -/* When using exists() don't auto-load a script. */ -static int no_autoload = FALSE; - /* * When recursively copying lists and dicts we need to remember which ones we * have done to avoid endless recursiveness. This unique ID is used for that. @@ -156,6 +153,11 @@ /* Values for trans_function_name() argument: */ #define TFN_INT 1 /* internal function name OK */ #define TFN_QUIET 2 /* no error messages */ +#define TFN_NO_AUTOLOAD 4 /* do not use script autoloading */ + +/* Values for get_lval() flags argument: */ +#define GLV_QUIET TFN_QUIET /* no error messages */ +#define GLV_NO_AUTOLOAD TFN_NO_AUTOLOAD /* do not use script autoloading */ /* * Structure to hold info for a user function. @@ -356,6 +358,7 @@ {VV_NAME("mouse_col", VAR_NUMBER), 0}, {VV_NAME("operator", VAR_STRING), VV_RO}, {VV_NAME("searchforward", VAR_NUMBER), 0}, + {VV_NAME("hlsearch", VAR_NUMBER), 0}, {VV_NAME("oldfiles", VAR_LIST), 0}, {VV_NAME("windowid", VAR_NUMBER), VV_RO}, }; @@ -389,7 +392,7 @@ static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg, int *first)); static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op)); static int check_changedtick __ARGS((char_u *arg)); -static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags)); +static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int flags, int fne_flags)); static void clear_lval __ARGS((lval_T *lp)); static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)); static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op)); @@ -444,7 +447,7 @@ #endif static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); static int find_internal_func __ARGS((char_u *name)); -static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); +static char_u *deref_func_name __ARGS((char_u *name, int *lenp, int no_autoload)); static int get_func_tv __ARGS((char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); static int call_func __ARGS((char_u *funcname, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); static void emsg_funcname __ARGS((char *ermsg, char_u *name)); @@ -474,7 +477,9 @@ static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); +static void byteidx __ARGS((typval_T *argvars, typval_T *rettv, int comp)); static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_byteidxcomp __ARGS((typval_T *argvars, typval_T *rettv)); static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); #ifdef FEAT_FLOAT static void f_ceil __ARGS((typval_T *argvars, typval_T *rettv)); @@ -767,7 +772,7 @@ static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); static int eval_isnamec __ARGS((int c)); static int eval_isnamec1 __ARGS((int c)); -static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); +static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose, int no_autoload)); static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); static typval_T *alloc_tv __ARGS((void)); static typval_T *alloc_string_tv __ARGS((char_u *string)); @@ -778,8 +783,8 @@ static char_u *get_tv_string __ARGS((typval_T *varp)); static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf)); -static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); -static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, int htname, char_u *varname, int writing)); +static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp, int no_autoload)); +static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, int htname, char_u *varname, int no_autoload)); static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); @@ -869,6 +874,7 @@ hash_add(&compat_hashtab, p->vv_di.di_key); } set_vim_var_nr(VV_SEARCHFORWARD, 1L); + set_vim_var_nr(VV_HLSEARCH, 1L); set_reg_var(0); /* default for v:register is not 0 but '"' */ #ifdef EBCDIC @@ -915,12 +921,13 @@ /* 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 */ @@ -1054,7 +1061,7 @@ ga_init2(&redir_ga, (int)sizeof(char), 500); /* Parse the variable name (can be a dict or list entry). */ - redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE, + redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, 0, FNE_CHECK_START); if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) { @@ -1145,7 +1152,7 @@ /* Call get_lval() again, if it's inside a Dict or List it may * have changed. */ redir_endp = get_lval(redir_varname, NULL, redir_lval, - FALSE, FALSE, FALSE, FNE_CHECK_START); + FALSE, FALSE, 0, FNE_CHECK_START); if (redir_endp != NULL && redir_lval->ll_name != NULL) set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)"."); clear_lval(redir_lval); @@ -2234,7 +2241,7 @@ { if (tofree != NULL) name = tofree; - if (get_var_tv(name, len, &tv, TRUE) == FAIL) + if (get_var_tv(name, len, &tv, TRUE, FALSE) == FAIL) error = TRUE; else { @@ -2469,7 +2476,7 @@ { lval_T lv; - p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); + p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START); if (p != NULL && lv.ll_name != NULL) { if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) @@ -2514,18 +2521,22 @@ * "unlet" is TRUE for ":unlet": slightly different behavior when something is * wrong; must end in space or cmd separator. * + * flags: + * GLV_QUIET: do not give error messages + * GLV_NO_AUTOLOAD: do not use script autoloading + * * Returns a pointer to just after the name, including indexes. * When an evaluation error occurs "lp->ll_name" is NULL; * Returns NULL for a parsing error. Still need to free items in "lp"! */ static char_u * -get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) +get_lval(name, rettv, lp, unlet, skip, flags, fne_flags) char_u *name; typval_T *rettv; lval_T *lp; int unlet; int skip; - int quiet; /* don't give error messages */ + int flags; /* GLV_ values */ int fne_flags; /* flags for find_name_end() */ { char_u *p; @@ -2539,6 +2550,7 @@ char_u *key = NULL; int len; hashtab_T *ht; + int quiet = flags & GLV_QUIET; /* Clear everything in "lp". */ vim_memset(lp, 0, sizeof(lval_T)); @@ -2586,7 +2598,7 @@ cc = *p; *p = NUL; - v = find_var(lp->ll_name, &ht); + v = find_var(lp->ll_name, &ht, flags & GLV_NO_AUTOLOAD); if (v == NULL && !quiet) EMSG2(_(e_undefvar), lp->ll_name); *p = cc; @@ -2899,7 +2911,7 @@ /* handle +=, -= and .= */ if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name), - &tv, TRUE) == OK) + &tv, TRUE, FALSE) == OK) { if (tv_op(&tv, rettv, op) == OK) set_var(lp->ll_name, &tv, FALSE); @@ -3420,7 +3432,7 @@ /* If it is the name of a variable of type VAR_FUNC use its contents. */ len = (int)STRLEN(tofree); - name = deref_func_name(tofree, &len); + name = deref_func_name(tofree, &len, FALSE); /* Skip white space to allow ":call func ()". Not good, but required for * backward compatibility. */ @@ -3551,7 +3563,7 @@ do { /* Parse the name and find the end. */ - name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, + name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, 0, FNE_CHECK_START); if (lv.ll_name == NULL) error = TRUE; /* error but continue parsing */ @@ -3704,7 +3716,7 @@ ret = FAIL; else { - di = find_var(lp->ll_name, NULL); + di = find_var(lp->ll_name, NULL, TRUE); if (di == NULL) ret = FAIL; else @@ -5147,7 +5159,7 @@ { /* If "s" is the name of a variable of type VAR_FUNC * use its contents. */ - s = deref_func_name(s, &len); + s = deref_func_name(s, &len, !evaluate); /* Invoke the function. */ ret = get_func_tv(s, len, rettv, arg, @@ -5174,7 +5186,7 @@ } } else if (evaluate) - ret = get_var_tv(s, len, rettv, TRUE); + ret = get_var_tv(s, len, rettv, TRUE, FALSE); else ret = OK; } @@ -6413,6 +6425,16 @@ if (ni == NULL) return FAIL; copy_tv(tv, &ni->li_tv); + list_insert(l, ni, item); + return OK; +} + + void +list_insert(l, ni, item) + list_T *l; + listitem_T *ni; + listitem_T *item; +{ if (item == NULL) /* Append new item at end of list. */ list_append(l, ni); @@ -6434,7 +6456,6 @@ item->li_prev = ni; ++l->lv_len; } - return OK; } /* @@ -7860,6 +7881,7 @@ {"bufwinnr", 1, 1, f_bufwinnr}, {"byte2line", 1, 1, f_byte2line}, {"byteidx", 2, 2, f_byteidx}, + {"byteidxcomp", 2, 2, f_byteidxcomp}, {"call", 2, 3, f_call}, #ifdef FEAT_FLOAT {"ceil", 1, 1, f_ceil}, @@ -8269,16 +8291,17 @@ * name it contains, otherwise return "name". */ static char_u * -deref_func_name(name, lenp) +deref_func_name(name, lenp, no_autoload) char_u *name; int *lenp; + int no_autoload; { dictitem_T *v; int cc; cc = name[*lenp]; name[*lenp] = NUL; - v = find_var(name, NULL); + v = find_var(name, NULL, no_autoload); name[*lenp] = cc; if (v != NULL && v->di_tv.v_type == VAR_FUNC) { @@ -9176,13 +9199,11 @@ #endif } -/* - * "byteidx()" function - */ static void -f_byteidx(argvars, rettv) +byteidx(argvars, rettv, comp) typval_T *argvars; typval_T *rettv; + int comp; { #ifdef FEAT_MBYTE char_u *t; @@ -9202,6 +9223,9 @@ { if (*t == NUL) /* EOL reached */ return; + if (enc_utf8 && comp) + t += utf_ptr2len(t); + else t += (*mb_ptr2len)(t); } rettv->vval.v_number = (varnumber_T)(t - str); @@ -9211,6 +9235,28 @@ #endif } +/* + * "byteidx()" function + */ + static void +f_byteidx(argvars, rettv) + typval_T *argvars; + typval_T *rettv; +{ + byteidx(argvars, rettv, FALSE); +} + +/* + * "byteidxcomp()" function + */ + static void +f_byteidxcomp(argvars, rettv) + typval_T *argvars; + typval_T *rettv; +{ + byteidx(argvars, rettv, TRUE); +} + int func_call(name, args, selfdict, rettv) char_u *name; @@ -10010,8 +10056,6 @@ int n = FALSE; int len = 0; - no_autoload = TRUE; - p = get_tv_string(&argvars[0]); if (*p == '$') /* environment variable */ { @@ -10062,7 +10106,7 @@ { if (tofree != NULL) name = tofree; - n = (get_var_tv(name, len, &tv, FALSE) == OK); + n = (get_var_tv(name, len, &tv, FALSE, TRUE) == OK); if (n) { /* handle d.key, l[idx], f(expr) */ @@ -10078,8 +10122,6 @@ } rettv->vval.v_number = n; - - no_autoload = FALSE; } #ifdef FEAT_FLOAT @@ -11090,6 +11132,8 @@ { char_u *p; + rettv->v_type = VAR_STRING; + rettv->vval.v_string = NULL; if (retlist && rettv_list_alloc(rettv) == FAIL) return; @@ -11102,8 +11146,6 @@ p = ml_get_buf(buf, start, FALSE); else p = (char_u *)""; - - rettv->v_type = VAR_STRING; rettv->vval.v_string = vim_strsave(p); } else @@ -12135,6 +12177,9 @@ #ifndef CASE_INSENSITIVE_FILENAME "fname_case", #endif +#ifdef HAVE_ACL + "acl", +#endif #ifdef FEAT_ARABIC "arabic", #endif @@ -12538,7 +12583,12 @@ "xfontset", #endif #ifdef FEAT_XPM_W32 - "xpm_w32", + "xpm", + "xpm_w32", /* for backward compatibility */ +#else +# if defined(HAVE_XPM) + "xpm", +# endif #endif #ifdef USE_XSMP "xsmp", @@ -13045,9 +13095,18 @@ } 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) @@ -13298,8 +13357,8 @@ dictitem_T *di; rettv->vval.v_number = -1; - end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, - FNE_CHECK_START); + end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, + GLV_NO_AUTOLOAD, FNE_CHECK_START); if (end != NULL && lv.ll_name != NULL) { if (*end != NUL) @@ -13312,7 +13371,7 @@ rettv->vval.v_number = 1; /* always locked */ else { - di = find_var(lv.ll_name, NULL); + di = find_var(lv.ll_name, NULL, TRUE); if (di != NULL) { /* Consider a variable locked when: @@ -14095,8 +14154,8 @@ } else { - list_append_string(rettv->vval.v_list, NUL, -1); - list_append_string(rettv->vval.v_list, NUL, -1); + list_append_string(rettv->vval.v_list, NULL, -1); + list_append_string(rettv->vval.v_list, NULL, -1); } } #endif @@ -14292,6 +14351,14 @@ return; dir = get_tv_string_buf(&argvars[0], buf); + if (*dir == NUL) + rettv->vval.v_number = FAIL; + else + { + if (*gettail(dir) == NUL) + /* remove trailing slashes */ + *gettail_sep(dir) = NUL; + if (argvars[1].v_type != VAR_UNKNOWN) { if (argvars[2].v_type != VAR_UNKNOWN) @@ -14299,7 +14366,8 @@ if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) mkdir_recurse(dir, prot); } - rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; + rettv->vval.v_number = prot == -1 ? FAIL : vim_mkdir_emsg(dir, prot); + } } #endif @@ -16881,7 +16949,7 @@ typval_T *argvars UNUSED; typval_T *rettv; { - rettv->vval.v_number = get_sw_value(); + rettv->vval.v_number = get_sw_value(curbuf); } /* @@ -19719,11 +19787,12 @@ * Return OK or FAIL. */ static int -get_var_tv(name, len, rettv, verbose) +get_var_tv(name, len, rettv, verbose, no_autoload) char_u *name; int len; /* length of "name" */ typval_T *rettv; /* NULL when only checking existence */ int verbose; /* may give error message */ + int no_autoload; /* do not use script autoloading */ { int ret = OK; typval_T *tv = NULL; @@ -19750,7 +19819,7 @@ */ else { - v = find_var(name, NULL); + v = find_var(name, NULL, no_autoload); if (v != NULL) tv = &v->di_tv; } @@ -19790,23 +19859,29 @@ while (ret == OK && (**arg == '[' || (**arg == '.' && rettv->v_type == VAR_DICT) - || (**arg == '(' && rettv->v_type == VAR_FUNC)) + || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC))) && !vim_iswhite(*(*arg - 1))) { if (**arg == '(') { /* need to copy the funcref so that we can clear rettv */ + if (evaluate) + { functv = *rettv; rettv->v_type = VAR_UNKNOWN; /* Invoke the function. Recursive! */ s = functv.vval.v_string; + } + else + s = (char_u *)""; ret = get_func_tv(s, (int)STRLEN(s), rettv, arg, curwin->w_cursor.lnum, curwin->w_cursor.lnum, &len, evaluate, selfdict); /* Clear the funcref afterwards, so that deleting it while * evaluating the arguments is possible (see test55). */ + if (evaluate) clear_tv(&functv); /* Stop the expression evaluation when immediately aborting on @@ -20146,9 +20221,10 @@ * hashtab_T used. */ static dictitem_T * -find_var(name, htp) +find_var(name, htp, no_autoload) char_u *name; hashtab_T **htp; + int no_autoload; { char_u *varname; hashtab_T *ht; @@ -20158,7 +20234,7 @@ *htp = ht; if (ht == NULL) return NULL; - return find_var_in_ht(ht, *name, varname, htp != NULL); + return find_var_in_ht(ht, *name, varname, no_autoload || htp != NULL); } /* @@ -20166,11 +20242,11 @@ * Returns NULL if not found. */ static dictitem_T * -find_var_in_ht(ht, htname, varname, writing) +find_var_in_ht(ht, htname, varname, no_autoload) hashtab_T *ht; int htname; char_u *varname; - int writing; + int no_autoload; { hashitem_T *hi; @@ -20202,7 +20278,7 @@ * worked find the variable again. Don't auto-load a script if it was * loaded already, otherwise it would be loaded every time when * checking if a function name is a Funcref variable. */ - if (ht == &globvarht && !writing) + if (ht == &globvarht && !no_autoload) { /* Note: script_autoload() may make "hi" invalid. It must either * be obtained again or not used. */ @@ -20282,7 +20358,7 @@ { dictitem_T *v; - v = find_var(name, NULL); + v = find_var(name, NULL, FALSE); if (v == NULL) return NULL; return get_tv_string(&v->di_tv); @@ -20560,6 +20636,13 @@ v->di_tv.vval.v_number = get_tv_number(tv); if (STRCMP(varname, "searchforward") == 0) set_search_direction(v->di_tv.vval.v_number ? '/' : '?'); +#ifdef FEAT_SEARCH_EXTRA + else if (STRCMP(varname, "hlsearch") == 0) + { + no_hlsearch = !v->di_tv.vval.v_number; + redraw_all_later(SOME_VALID); + } +#endif } return; } @@ -21604,7 +21687,7 @@ */ if (fudi.fd_dict == NULL) { - v = find_var(name, &ht); + v = find_var(name, &ht, FALSE); if (v != NULL && v->di_tv.v_type == VAR_FUNC) { emsg_funcname(N_("E707: Function name conflicts with variable: %s"), @@ -21764,6 +21847,7 @@ * flags: * TFN_INT: internal function name OK * TFN_QUIET: be quiet + * TFN_NO_AUTOLOAD: do not use script autoloading * Advances "pp" to just after the function name (if no error). */ static char_u * @@ -21801,7 +21885,8 @@ if (lead > 2) start += lead; - end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, + /* Note that TFN_ flags use the same values as GLV_ flags. */ + end = get_lval(start, NULL, &lv, FALSE, skip, flags, lead > 2 ? 0 : FNE_CHECK_START); if (end == start) { @@ -21863,14 +21948,14 @@ if (lv.ll_exp_name != NULL) { len = (int)STRLEN(lv.ll_exp_name); - name = deref_func_name(lv.ll_exp_name, &len); + name = deref_func_name(lv.ll_exp_name, &len, flags & TFN_NO_AUTOLOAD); if (name == lv.ll_exp_name) name = NULL; } else { len = (int)(end - *pp); - name = deref_func_name(*pp, &len); + name = deref_func_name(*pp, &len, flags & TFN_NO_AUTOLOAD); if (name == *pp) name = NULL; } @@ -22078,7 +22163,8 @@ char_u *p; int n = FALSE; - p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET, NULL); + p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD, + NULL); nm = skipwhite(nm); /* Only accept "funcname", "funcname ", "funcname (..." and @@ -22325,10 +22411,6 @@ int ret = FALSE; int i; - /* Return quickly when autoload disabled. */ - if (no_autoload) - return FALSE; - /* If there is no '#' after name[0] there is no package name. */ p = vim_strchr(name, AUTOLOAD_CHAR); if (p == NULL || p == name) @@ -24283,6 +24365,7 @@ garray_T ga; char_u *ret; char_u *save_cpo; + char_u *zero_width = NULL; /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ save_cpo = p_cpo; @@ -24299,6 +24382,19 @@ tail = str; while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) { + /* Skip empty match except for first match. */ + if (regmatch.startp[0] == regmatch.endp[0]) + { + if (zero_width == regmatch.startp[0]) + { + /* avoid getting stuck on a match with an empty string */ + *((char_u *)ga.ga_data + ga.ga_len) = *tail++; + ++ga.ga_len; + continue; + } + zero_width = regmatch.startp[0]; + } + /* * Get some space for a temporary buffer to do the substitution * into. It will contain: @@ -24321,20 +24417,9 @@ (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]) - { - if (*tail == NUL) - break; - *((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 -ubBwrN ../../work/vim74/src/ex_cmds.c ./src/ex_cmds.c --- ../../work/vim74/src/ex_cmds.c 2013-08-07 16:15:51.000000000 +0300 +++ ./src/ex_cmds.c 2014-02-22 19:30:45.000000000 +0300 @@ -3253,8 +3253,10 @@ if ( ((!other_file && !(flags & ECMD_OLDBUF)) || (curbuf->b_nwindows == 1 && !(flags & (ECMD_HIDE | ECMD_ADDBUF)))) - && check_changed(curbuf, p_awa, !other_file, - (flags & ECMD_FORCEIT), FALSE)) + && check_changed(curbuf, (p_awa ? CCGD_AW : 0) + | (other_file ? 0 : CCGD_MULTWIN) + | ((flags & ECMD_FORCEIT) ? CCGD_FORCEIT : 0) + | (eap == NULL ? 0 : CCGD_EXCMD))) { if (fnum == 0 && other_file && ffname != NULL) (void)setaltfname(ffname, sfname, newlnum < 0 ? 0 : newlnum); @@ -4740,11 +4742,17 @@ 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(' '); @@ -5928,14 +5936,18 @@ "?", ":?", "?", "g?", "g?g?", "g??", "z?", "/\\?", "/\\z(\\)", "\\=", ":s\\=", "[count]", "[quotex]", "[range]", - "[pattern]", "\\|", "\\%$"}; + "[pattern]", "\\|", "\\%$", + "s/\\~", "s/\\U", "s/\\L", + "s/\\1", "s/\\2", "s/\\3", "s/\\9"}; static char *(rtable[]) = {"star", "gstar", "[star", "]star", ":star", "/star", "/\\\\star", "quotestar", "starstar", "cpo-star", "/\\\\(\\\\)", "/\\\\%(\\\\)", "?", ":?", "?", "g?", "g?g?", "g??", "z?", "/\\\\?", "/\\\\z(\\\\)", "\\\\=", ":s\\\\=", "\\[count]", "\\[quotex]", "\\[range]", - "\\[pattern]", "\\\\bar", "/\\\\%\\$"}; + "\\[pattern]", "\\\\bar", "/\\\\%\\$", + "s/\\\\\\~", "s/\\\\U", "s/\\\\L", + "s/\\\\1", "s/\\\\2", "s/\\\\3", "s/\\\\9"}; int flags; d = IObuff; /* assume IObuff is long enough! */ @@ -5974,7 +5986,7 @@ /* Replace: * "[:...:]" with "\[:...:]" * "[++...]" with "\[++...]" - * "\{" with "\\{" + * "\{" with "\\{" -- matching "} \}" */ if ((arg[0] == '[' && (arg[1] == ':' || (arg[1] == '+' && arg[2] == '+'))) @@ -7658,7 +7670,7 @@ # ifdef FEAT_WINDOWS ++emsg_off; # endif - split = check_changed(curbuf, TRUE, FALSE, FALSE, FALSE); + split = check_changed(curbuf, CCGD_AW | CCGD_EXCMD); # ifdef FEAT_WINDOWS --emsg_off; # else diff -ubBwrN ../../work/vim74/src/ex_cmds.h ./src/ex_cmds.h --- ../../work/vim74/src/ex_cmds.h 2013-06-08 16:08:20.000000000 +0300 +++ ./src/ex_cmds.h 2014-02-22 19:30:42.000000000 +0300 @@ -477,6 +477,8 @@ NEEDARG|EXTRA|NOTRLCOM), EX(CMD_keepjumps, "keepjumps", ex_wrongmodifier, NEEDARG|EXTRA|NOTRLCOM), +EX(CMD_keeppatterns, "keeppatterns", ex_wrongmodifier, + NEEDARG|EXTRA|NOTRLCOM), EX(CMD_keepalt, "keepalt", ex_wrongmodifier, NEEDARG|EXTRA|NOTRLCOM), EX(CMD_list, "list", ex_print, diff -ubBwrN ../../work/vim74/src/ex_cmds2.c ./src/ex_cmds2.c --- ../../work/vim74/src/ex_cmds2.c 2013-06-28 21:14:53.000000000 +0300 +++ ./src/ex_cmds2.c 2014-02-22 19:30:42.000000000 +0300 @@ -1436,20 +1436,20 @@ } /* - * return TRUE if buffer was changed and cannot be abandoned. + * Return TRUE if buffer was changed and cannot be abandoned. + * For flags use the CCGD_ values. */ int -check_changed(buf, checkaw, mult_win, forceit, allbuf) +check_changed(buf, flags) buf_T *buf; - int checkaw; /* do autowrite if buffer was changed */ - int mult_win; /* check also when several wins for the buf */ - int forceit; - int allbuf UNUSED; /* may write all buffers */ + int flags; { + int forceit = (flags & CCGD_FORCEIT); + if ( !forceit && bufIsChanged(buf) - && (mult_win || buf->b_nwindows <= 1) - && (!checkaw || autowrite(buf, forceit) == FAIL)) + && ((flags & CCGD_MULTWIN) || buf->b_nwindows <= 1) + && (!(flags & CCGD_AW) || autowrite(buf, forceit) == FAIL)) { #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) if ((p_confirm || cmdmod.confirm) && p_write) @@ -1457,7 +1457,7 @@ buf_T *buf2; int count = 0; - if (allbuf) + if (flags & CCGD_ALLBUF) for (buf2 = firstbuf; buf2 != NULL; buf2 = buf2->b_next) if (bufIsChanged(buf2) && (buf2->b_ffname != NULL @@ -1480,7 +1480,10 @@ return bufIsChanged(buf); } #endif + if (flags & CCGD_EXCMD) EMSG(_(e_nowrtmsg)); + else + EMSG(_(e_nowrtmsg_nobang)); return TRUE; } return FALSE; @@ -1690,7 +1693,9 @@ { /* Try auto-writing the buffer. If this fails but the buffer no * longer exists it's not changed, that's OK. */ - if (check_changed(buf, p_awa, TRUE, FALSE, TRUE) && buf_valid(buf)) + if (check_changed(buf, (p_awa ? CCGD_AW : 0) + | CCGD_MULTWIN + | CCGD_ALLBUF) && buf_valid(buf)) break; /* didn't save - still changes */ } } @@ -2274,7 +2279,10 @@ vim_free(p); } if ((!P_HID(curbuf) || !other) - && check_changed(curbuf, TRUE, !other, eap->forceit, FALSE)) + && check_changed(curbuf, CCGD_AW + | (other ? 0 : CCGD_MULTWIN) + | (eap->forceit ? CCGD_FORCEIT : 0) + | CCGD_EXCMD)) return; } @@ -2315,7 +2323,9 @@ */ if ( P_HID(curbuf) || eap->cmdidx == CMD_snext - || !check_changed(curbuf, TRUE, FALSE, eap->forceit, FALSE)) + || !check_changed(curbuf, CCGD_AW + | (eap->forceit ? CCGD_FORCEIT : 0) + | CCGD_EXCMD)) { if (*eap->arg != NUL) /* redefine file list */ { @@ -2458,7 +2468,9 @@ if (eap->cmdidx == CMD_windo || eap->cmdidx == CMD_tabdo || P_HID(curbuf) - || !check_changed(curbuf, TRUE, FALSE, eap->forceit, FALSE)) + || !check_changed(curbuf, CCGD_AW + | (eap->forceit ? CCGD_FORCEIT : 0) + | CCGD_EXCMD)) { /* start at the first argument/window/buffer */ i = 0; diff -ubBwrN ../../work/vim74/src/ex_docmd.c ./src/ex_docmd.c --- ../../work/vim74/src/ex_docmd.c 2013-07-24 16:09:37.000000000 +0300 +++ ./src/ex_docmd.c 2014-02-22 19:30:45.000000000 +0300 @@ -1843,6 +1843,11 @@ cmdmod.keepalt = TRUE; continue; } + if (checkforcmd(&ea.cmd, "keeppatterns", 5)) + { + cmdmod.keeppatterns = TRUE; + continue; + } if (!checkforcmd(&ea.cmd, "keepjumps", 5)) break; cmdmod.keepjumps = TRUE; @@ -2584,6 +2589,7 @@ case CMD_keepalt: case CMD_keepjumps: case CMD_keepmarks: + case CMD_keeppatterns: case CMD_leftabove: case CMD_let: case CMD_lockmarks: @@ -3089,6 +3095,7 @@ {"keepalt", 5, FALSE}, {"keepjumps", 5, FALSE}, {"keepmarks", 3, FALSE}, + {"keeppatterns", 5, FALSE}, {"leftabove", 5, FALSE}, {"lockmarks", 3, FALSE}, {"noautocmd", 3, FALSE}, @@ -3254,7 +3261,11 @@ ++p; /* for python 3.x: ":py3*" commands completion */ if (cmd[0] == 'p' && cmd[1] == 'y' && p == cmd + 2 && *p == '3') + { ++p; + while (ASCII_ISALPHA(*p) || *p == '*') + ++p; + } len = (int)(p - cmd); if (len == 0) @@ -3597,6 +3608,7 @@ case CMD_keepalt: case CMD_keepjumps: case CMD_keepmarks: + case CMD_keeppatterns: case CMD_leftabove: case CMD_lockmarks: case CMD_rightbelow: @@ -6565,7 +6577,9 @@ if (check_more(FALSE, eap->forceit) == OK && only_one_window()) exiting = TRUE; if ((!P_HID(curbuf) - && check_changed(curbuf, p_awa, FALSE, eap->forceit, FALSE)) + && check_changed(curbuf, (p_awa ? CCGD_AW : 0) + | (eap->forceit ? CCGD_FORCEIT : 0) + | CCGD_EXCMD)) || check_more(TRUE, eap->forceit) == FAIL || (only_one_window() && check_changed_any(eap->forceit))) { @@ -7099,7 +7113,7 @@ if (!P_HID(curbuf) && !split) { ++emsg_off; - split = check_changed(curbuf, TRUE, FALSE, FALSE, FALSE); + split = check_changed(curbuf, CCGD_AW); --emsg_off; } if (split) @@ -7361,7 +7375,11 @@ { /* Set recoverymode right away to avoid the ATTENTION prompt. */ recoverymode = TRUE; - if (!check_changed(curbuf, p_awa, TRUE, eap->forceit, FALSE) + if (!check_changed(curbuf, (p_awa ? CCGD_AW : 0) + | CCGD_MULTWIN + | (eap->forceit ? CCGD_FORCEIT : 0) + | CCGD_EXCMD) + && (*eap->arg == NUL || setfname(curbuf, eap->arg, NULL, TRUE) == OK)) ml_recover(); @@ -8036,6 +8054,8 @@ { #ifdef FEAT_SCROLLBIND win_T *wp; + win_T *save_curwin = curwin; + buf_T *save_curbuf = curbuf; long topline; long y; linenr_T old_linenr = curwin->w_cursor.lnum; @@ -8067,13 +8087,13 @@ /* - * set all scrollbind windows to the same topline + * Set all scrollbind windows to the same topline. */ - wp = curwin; for (curwin = firstwin; curwin; curwin = curwin->w_next) { if (curwin->w_p_scb) { + curbuf = curwin->w_buffer; y = topline - curwin->w_topline; if (y > 0) scrollup(y, TRUE); @@ -8087,7 +8107,8 @@ #endif } } - curwin = wp; + curwin = save_curwin; + curbuf = save_curbuf; if (curwin->w_p_scb) { did_syncbind = TRUE; @@ -8207,6 +8228,7 @@ int local; { vim_free(curwin->w_localdir); + curwin->w_localdir = NULL; if (local) { /* If still in global directory, need to remember current @@ -8223,7 +8245,6 @@ * name. */ vim_free(globaldir); globaldir = NULL; - curwin->w_localdir = NULL; } shorten_fnames(TRUE); @@ -8350,7 +8371,7 @@ { n = W_WINROW(curwin) + curwin->w_wrow - msg_scrolled; if (n >= 0) - windgoto((int)n, curwin->w_wcol); + windgoto((int)n, W_WINCOL(curwin) + curwin->w_wcol); } len = eap->line2; @@ -8556,6 +8577,11 @@ beginline(BL_SOL | BL_FIX); } +#if defined(FEAT_VISUAL) + if (VIsual_active) + end_visual_mode(); +#endif + switch (eap->cmdidx) { case CMD_delete: @@ -11389,7 +11415,7 @@ ex_nohlsearch(eap) exarg_T *eap UNUSED; { - no_hlsearch = TRUE; + SET_NO_HLSEARCH(TRUE); redraw_all_later(SOME_VALID); } diff -ubBwrN ../../work/vim74/src/ex_eval.c ./src/ex_eval.c --- ../../work/vim74/src/ex_eval.c 2013-06-08 16:50:28.000000000 +0300 +++ ./src/ex_eval.c 2014-02-22 19:30:43.000000000 +0300 @@ -321,6 +321,17 @@ } /* + * Free global "*msg_list" and the messages it contains, then set "*msg_list" + * to NULL. + */ + void +free_global_msglist() +{ + free_msglist(*msg_list); + *msg_list = NULL; +} + +/* * Throw the message specified in the call to cause_errthrow() above as an * error exception. If cstack is NULL, postpone the throw until do_cmdline() * has returned (see do_one_cmd()). @@ -410,66 +421,41 @@ return TRUE; } - /* - * Throw a new exception. Return FAIL when out of memory or it was tried to - * throw an illegal user exception. "value" is the exception string for a user - * or interrupt exception, or points to a message list in case of an error - * exception. + * Get an exception message that is to be stored in current_exception->value. */ - static int -throw_exception(value, type, cmdname) + char_u * +get_exception_string(value, type, cmdname, should_free) void *value; int type; char_u *cmdname; + int *should_free; { - except_T *excp; - char_u *p, *mesg, *val; + char_u *ret, *mesg; int cmdlen; - - /* - * Disallow faking Interrupt or error exceptions as user exceptions. They - * would be treated differently from real interrupt or error exceptions when - * no active try block is found, see do_cmdline(). - */ - if (type == ET_USER) - { - if (STRNCMP((char_u *)value, "Vim", 3) == 0 && - (((char_u *)value)[3] == NUL || ((char_u *)value)[3] == ':' || - ((char_u *)value)[3] == '(')) - { - EMSG(_("E608: Cannot :throw exceptions with 'Vim' prefix")); - goto fail; - } - } - - excp = (except_T *)alloc((unsigned)sizeof(except_T)); - if (excp == NULL) - goto nomem; + char_u *p, *val; if (type == ET_ERROR) { - /* Store the original message and prefix the exception value with - * "Vim:" or, if a command name is given, "Vim(cmdname):". */ - excp->messages = (struct msglist *)value; - mesg = excp->messages->throw_msg; + *should_free = FALSE; + mesg = ((struct msglist *)value)->throw_msg; if (cmdname != NULL && *cmdname != NUL) { cmdlen = (int)STRLEN(cmdname); - excp->value = vim_strnsave((char_u *)"Vim(", + ret = vim_strnsave((char_u *)"Vim(", 4 + cmdlen + 2 + (int)STRLEN(mesg)); - if (excp->value == NULL) - goto nomem; - STRCPY(&excp->value[4], cmdname); - STRCPY(&excp->value[4 + cmdlen], "):"); - val = excp->value + 4 + cmdlen + 2; + if (ret == NULL) + return ret; + STRCPY(&ret[4], cmdname); + STRCPY(&ret[4 + cmdlen], "):"); + val = ret + 4 + cmdlen + 2; } else { - excp->value = vim_strnsave((char_u *)"Vim:", 4 + (int)STRLEN(mesg)); - if (excp->value == NULL) - goto nomem; - val = excp->value + 4; + ret = vim_strnsave((char_u *)"Vim:", 4 + (int)STRLEN(mesg)); + if (ret == NULL) + return ret; + val = ret + 4; } /* msg_add_fname may have been used to prefix the message with a file @@ -506,14 +492,65 @@ } } else - excp->value = value; + { + *should_free = FALSE; + ret = (char_u *) value; + } + + return ret; +} + + +/* + * Throw a new exception. Return FAIL when out of memory or it was tried to + * throw an illegal user exception. "value" is the exception string for a + * user or interrupt exception, or points to a message list in case of an + * error exception. + */ + static int +throw_exception(value, type, cmdname) + void *value; + int type; + char_u *cmdname; +{ + except_T *excp; + int should_free; + + /* + * Disallow faking Interrupt or error exceptions as user exceptions. They + * would be treated differently from real interrupt or error exceptions + * when no active try block is found, see do_cmdline(). + */ + if (type == ET_USER) + { + if (STRNCMP((char_u *)value, "Vim", 3) == 0 + && (((char_u *)value)[3] == NUL || ((char_u *)value)[3] == ':' + || ((char_u *)value)[3] == '(')) + { + EMSG(_("E608: Cannot :throw exceptions with 'Vim' prefix")); + goto fail; + } + } + + excp = (except_T *)alloc((unsigned)sizeof(except_T)); + if (excp == NULL) + goto nomem; + + if (type == ET_ERROR) + /* Store the original message and prefix the exception value with + * "Vim:" or, if a command name is given, "Vim(cmdname):". */ + excp->messages = (struct msglist *)value; + + excp->value = get_exception_string(value, type, cmdname, &should_free); + if (excp->value == NULL && should_free) + goto nomem; excp->type = type; excp->throw_name = vim_strsave(sourcing_name == NULL ? (char_u *)"" : sourcing_name); if (excp->throw_name == NULL) { - if (type == ET_ERROR) + if (should_free) vim_free(excp->value); goto nomem; } @@ -2033,10 +2070,7 @@ /* If an error was about to be converted to an exception when * enter_cleanup() was called, free the message list. */ if (msg_list != NULL) - { - free_msglist(*msg_list); - *msg_list = NULL; - } + free_global_msglist(); } /* diff -ubBwrN ../../work/vim74/src/ex_getln.c ./src/ex_getln.c --- ../../work/vim74/src/ex_getln.c 2013-07-05 20:44:21.000000000 +0300 +++ ./src/ex_getln.c 2014-02-22 19:30:43.000000000 +0300 @@ -2280,7 +2280,7 @@ if (c1 == Ctrl_T) { - long sw = get_sw_value(); + long sw = get_sw_value(curbuf); p = (char_u *)line_ga.ga_data; p[line_ga.ga_len] = NUL; @@ -2337,7 +2337,7 @@ p[line_ga.ga_len] = NUL; indent = get_indent_str(p, 8); --indent; - indent -= indent % get_sw_value(); + indent -= indent % get_sw_value(curbuf); } while (get_indent_str(p, 8) > indent) { @@ -3852,9 +3852,9 @@ char_u buf[20]; int j = 0; - /* Don't escape '[' and '{' if they are in 'isfname'. */ + /* Don't escape '[', '{' and '!' if they are in 'isfname'. */ for (p = PATH_ESC_CHARS; *p != NUL; ++p) - if ((*p != '[' && *p != '{') || !vim_isfilec(*p)) + if ((*p != '[' && *p != '{' && *p != '!') || !vim_isfilec(*p)) buf[j++] = *p; buf[j] = NUL; p = vim_strsave_escaped(fname, buf); @@ -4178,7 +4178,7 @@ /* * Prepare a string for expansion. * When expanding file names: The string will be used with expand_wildcards(). - * Copy the file name into allocated memory and add a '*' at the end. + * Copy "fname[len]" into allocated memory and add a '*' at the end. * When expanding other names: The string will be used with regcomp(). Copy * the name into allocated memory and prepend "^". */ @@ -5498,6 +5498,9 @@ if (hislen == 0) /* no history */ return; + if (cmdmod.keeppatterns && histype == HIST_SEARCH) + return; + /* * Searches inside the same mapping overwrite each other, so that only * the last line is kept. Be careful not to remove a line that was moved diff -ubBwrN ../../work/vim74/src/fileio.c ./src/fileio.c --- ../../work/vim74/src/fileio.c 2013-08-05 22:58:03.000000000 +0300 +++ ./src/fileio.c 2014-02-22 19:30:45.000000000 +0300 @@ -428,13 +428,13 @@ } } + if (!read_stdin && !read_buffer) + { #ifdef UNIX /* * On Unix it is possible to read a directory, so we have to * check for it before the mch_open(). */ - if (!read_stdin && !read_buffer) - { perm = mch_getperm(fname); if (perm >= 0 && !S_ISREG(perm) /* not a regular file ... */ # ifdef S_ISFIFO @@ -457,7 +457,7 @@ msg_scroll = msg_save; return FAIL; } - +#endif # if defined(MSDOS) || defined(MSWIN) || defined(OS2) /* * MS-Windows allows opening a device, but we will probably get stuck @@ -472,7 +472,6 @@ } # endif } -#endif /* Set default or forced 'fileformat' and 'binary'. */ set_file_options(set_options, eap); @@ -2926,9 +2925,14 @@ int *did_ask; /* flag: whether already asked for key */ { int method = crypt_method_from_magic((char *)ptr, *sizep); + int b_p_ro = curbuf->b_p_ro; if (method >= 0) { + /* Mark the buffer as read-only until the decryption has taken place. + * Avoids accidentally overwriting the file with garbage. */ + curbuf->b_p_ro = TRUE; + set_crypt_method(curbuf, method); if (method > 0) (void)blowfish_self_test(); @@ -2969,7 +2973,7 @@ else { bf_key_init(cryptkey, ptr + CRYPT_MAGIC_LEN, salt_len); - bf_ofb_init(ptr + CRYPT_MAGIC_LEN + salt_len, seed_len); + bf_cfb_init(ptr + CRYPT_MAGIC_LEN + salt_len, seed_len); } /* Remove magic number from the text */ @@ -2977,6 +2981,8 @@ *sizep -= CRYPT_MAGIC_LEN + salt_len + seed_len; mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN + salt_len + seed_len, (size_t)*sizep); + /* Restore the read-only flag. */ + curbuf->b_p_ro = b_p_ro; } } /* When starting to edit a new file which does not have encryption, clear @@ -3019,7 +3025,7 @@ if (fread(buffer, salt_len + seed_len, 1, fp) != 1) return FAIL; bf_key_init(curbuf->b_p_key, buffer, salt_len); - bf_ofb_init(buffer + salt_len, seed_len); + bf_cfb_init(buffer + salt_len, seed_len); } return OK; } @@ -3058,7 +3064,7 @@ seed = salt + salt_len; sha2_seed(salt, salt_len, seed, seed_len); bf_key_init(buf->b_p_key, salt, salt_len); - bf_ofb_init(seed, seed_len); + bf_cfb_init(seed, seed_len); } } *lenp = CRYPT_MAGIC_LEN + salt_len + seed_len; @@ -6701,6 +6707,9 @@ mch_set_acl(to, acl); mch_free_acl(acl); #endif +#ifdef HAVE_SELINUX + mch_copy_sec(from, to); +#endif if (errmsg != NULL) { EMSG2(errmsg, to); @@ -9321,7 +9330,9 @@ */ if (fname_io == NULL) { - if (fname != NULL && *fname != NUL) + if (event == EVENT_COLORSCHEME) + autocmd_fname = NULL; + else if (fname != NULL && *fname != NUL) autocmd_fname = fname; else if (buf != NULL) autocmd_fname = buf->b_ffname; @@ -9374,14 +9385,15 @@ else { sfname = vim_strsave(fname); - /* Don't try expanding FileType, Syntax, FuncUndefined, WindowID or - * QuickFixCmd* */ + /* Don't try expanding FileType, Syntax, FuncUndefined, WindowID, + * ColorScheme or QuickFixCmd* */ if (event == EVENT_FILETYPE || event == EVENT_SYNTAX || event == EVENT_FUNCUNDEFINED || event == EVENT_REMOTEREPLY || event == EVENT_SPELLFILEMISSING || event == EVENT_QUICKFIXCMDPRE + || event == EVENT_COLORSCHEME || event == EVENT_QUICKFIXCMDPOST) fname = vim_strsave(fname); else diff -ubBwrN ../../work/vim74/src/fold.c ./src/fold.c --- ../../work/vim74/src/fold.c 2013-06-15 17:57:24.000000000 +0300 +++ ./src/fold.c 2014-02-22 19:30:42.000000000 +0300 @@ -3052,7 +3052,7 @@ flp->lvl = -1; } else - flp->lvl = get_indent_buf(buf, lnum) / get_sw_value(); + flp->lvl = get_indent_buf(buf, lnum) / get_sw_value(curbuf); if (flp->lvl > flp->wp->w_p_fdn) { flp->lvl = flp->wp->w_p_fdn; diff -ubBwrN ../../work/vim74/src/getchar.c ./src/getchar.c --- ../../work/vim74/src/getchar.c 2013-06-29 14:43:27.000000000 +0300 +++ ./src/getchar.c 2014-02-22 19:30:46.000000000 +0300 @@ -40,13 +40,13 @@ #define MINIMAL_SIZE 20 /* minimal size for b_str */ -static struct buffheader redobuff = {{NULL, {NUL}}, NULL, 0, 0}; -static struct buffheader old_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; +static buffheader_T redobuff = {{NULL, {NUL}}, NULL, 0, 0}; +static buffheader_T old_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; #if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO) -static struct buffheader save_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; -static struct buffheader save_old_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; +static buffheader_T save_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; +static buffheader_T save_old_redobuff = {{NULL, {NUL}}, NULL, 0, 0}; #endif -static struct buffheader recordbuff = {{NULL, {NUL}}, NULL, 0, 0}; +static buffheader_T recordbuff = {{NULL, {NUL}}, NULL, 0, 0}; static int typeahead_char = 0; /* typeahead char that's not flushed */ @@ -112,11 +112,12 @@ static int last_recorded_len = 0; /* number of last recorded chars */ -static char_u *get_buffcont __ARGS((struct buffheader *, int)); -static void add_buff __ARGS((struct buffheader *, char_u *, long n)); -static void add_num_buff __ARGS((struct buffheader *, long)); -static void add_char_buff __ARGS((struct buffheader *, int)); -static int read_stuff __ARGS((int advance)); +static char_u *get_buffcont __ARGS((buffheader_T *, int)); +static void add_buff __ARGS((buffheader_T *, char_u *, long n)); +static void add_num_buff __ARGS((buffheader_T *, long)); +static void add_char_buff __ARGS((buffheader_T *, int)); +static int read_readbuffers __ARGS((int advance)); +static int read_readbuf __ARGS((buffheader_T *buf, int advance)); static void start_stuff __ARGS((void)); static int read_redo __ARGS((int, int)); static void copy_redo __ARGS((int)); @@ -137,9 +138,9 @@ */ void free_buff(buf) - struct buffheader *buf; + buffheader_T *buf; { - struct buffblock *p, *np; + buffblock_T *p, *np; for (p = buf->bh_first.b_next; p != NULL; p = np) { @@ -155,14 +156,14 @@ */ static char_u * get_buffcont(buffer, dozero) - struct buffheader *buffer; + buffheader_T *buffer; int dozero; /* count == zero is not an error */ { long_u count = 0; char_u *p = NULL; char_u *p2; char_u *str; - struct buffblock *bp; + buffblock_T *bp; /* compute the total length of the string */ for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next) @@ -230,11 +231,11 @@ */ static void add_buff(buf, s, slen) - struct buffheader *buf; + buffheader_T *buf; char_u *s; long slen; /* length of "s" or -1 */ { - struct buffblock *p; + buffblock_T *p; long_u len; if (slen < 0) @@ -270,7 +271,7 @@ len = MINIMAL_SIZE; else len = slen; - p = (struct buffblock *)lalloc((long_u)(sizeof(struct buffblock) + len), + p = (buffblock_T *)lalloc((long_u)(sizeof(buffblock_T) + len), TRUE); if (p == NULL) return; /* no space, just forget it */ @@ -289,7 +290,7 @@ */ static void add_num_buff(buf, n) - struct buffheader *buf; + buffheader_T *buf; long n; { char_u number[32]; @@ -304,7 +305,7 @@ */ static void add_char_buff(buf, c) - struct buffheader *buf; + buffheader_T *buf; int c; { #ifdef FEAT_MBYTE @@ -354,46 +355,71 @@ #endif } +/* First read ahead buffer. Used for translated commands. */ +static buffheader_T readbuf1 = {{NULL, {NUL}}, NULL, 0, 0}; + +/* Second read ahead buffer. Used for redo. */ +static buffheader_T readbuf2 = {{NULL, {NUL}}, NULL, 0, 0}; + /* - * Get one byte from the stuff buffer. + * Get one byte from the read buffers. Use readbuf1 one first, use readbuf2 + * if that one is empty. * If advance == TRUE go to the next char. * No translation is done K_SPECIAL and CSI are escaped. */ static int -read_stuff(advance) +read_readbuffers(advance) + int advance; +{ + int c; + + c = read_readbuf(&readbuf1, advance); + if (c == NUL) + c = read_readbuf(&readbuf2, advance); + return c; +} + + static int +read_readbuf(buf, advance) + buffheader_T *buf; int advance; { char_u c; - struct buffblock *curr; + buffblock_T *curr; - if (stuffbuff.bh_first.b_next == NULL) /* buffer is empty */ + if (buf->bh_first.b_next == NULL) /* buffer is empty */ return NUL; - curr = stuffbuff.bh_first.b_next; - c = curr->b_str[stuffbuff.bh_index]; + curr = buf->bh_first.b_next; + c = curr->b_str[buf->bh_index]; if (advance) { - if (curr->b_str[++stuffbuff.bh_index] == NUL) + if (curr->b_str[++buf->bh_index] == NUL) { - stuffbuff.bh_first.b_next = curr->b_next; + buf->bh_first.b_next = curr->b_next; vim_free(curr); - stuffbuff.bh_index = 0; + buf->bh_index = 0; } } return c; } /* - * Prepare the stuff buffer for reading (if it contains something). + * Prepare the read buffers for reading (if they contain something). */ static void start_stuff() { - if (stuffbuff.bh_first.b_next != NULL) + if (readbuf1.bh_first.b_next != NULL) + { + readbuf1.bh_curr = &(readbuf1.bh_first); + readbuf1.bh_space = 0; + } + if (readbuf2.bh_first.b_next != NULL) { - stuffbuff.bh_curr = &(stuffbuff.bh_first); - stuffbuff.bh_space = 0; + readbuf2.bh_curr = &(readbuf2.bh_first); + readbuf2.bh_space = 0; } } @@ -403,7 +429,18 @@ int stuff_empty() { - return (stuffbuff.bh_first.b_next == NULL); + return (readbuf1.bh_first.b_next == NULL + && readbuf2.bh_first.b_next == NULL); +} + +/* + * Return TRUE if readbuf1 is empty. There may still be redo characters in + * redbuf2. + */ + int +readbuf1_empty() +{ + return (readbuf1.bh_first.b_next == NULL); } /* @@ -428,7 +465,7 @@ init_typebuf(); start_stuff(); - while (read_stuff(TRUE) != NUL) + while (read_readbuffers(TRUE) != NUL) ; if (flush_typeahead) /* remove all typeahead */ @@ -483,7 +520,7 @@ redobuff = old_redobuff; old_redobuff.bh_first.b_next = NULL; start_stuff(); - while (read_stuff(TRUE) != NUL) + while (read_readbuffers(TRUE) != NUL) ; } } @@ -638,7 +675,7 @@ stuffReadbuff(s) char_u *s; { - add_buff(&stuffbuff, s, -1L); + add_buff(&readbuf1, s, -1L); } void @@ -646,7 +683,7 @@ char_u *s; long len; { - add_buff(&stuffbuff, s, len); + add_buff(&readbuf1, s, len); } #if defined(FEAT_EVAL) || defined(PROTO) @@ -692,7 +729,7 @@ stuffcharReadbuff(c) int c; { - add_char_buff(&stuffbuff, c); + add_char_buff(&readbuf1, c); } /* @@ -702,7 +739,7 @@ stuffnumReadbuff(n) long n; { - add_num_buff(&stuffbuff, n); + add_num_buff(&readbuf1, n); } /* @@ -718,7 +755,7 @@ int init; int old_redo; { - static struct buffblock *bp; + static buffblock_T *bp; static char_u *p; int c; #ifdef FEAT_MBYTE @@ -795,11 +832,11 @@ int c; while ((c = read_redo(FALSE, old_redo)) != NUL) - stuffcharReadbuff(c); + add_char_buff(&readbuf2, c); } /* - * Stuff the redo buffer into the stuffbuff. + * Stuff the redo buffer into readbuf2. * Insert the redo count into the command. * If "old_redo" is TRUE, the last but one command is repeated * instead of the last command (inserting text). This is used for @@ -823,13 +860,13 @@ /* copy the buffer name, if present */ if (c == '"') { - add_buff(&stuffbuff, (char_u *)"\"", 1L); + add_buff(&readbuf2, (char_u *)"\"", 1L); c = read_redo(FALSE, old_redo); /* if a numbered buffer is used, increment the number */ if (c >= '1' && c < '9') ++c; - add_char_buff(&stuffbuff, c); + add_char_buff(&readbuf2, c); c = read_redo(FALSE, old_redo); } @@ -850,18 +887,18 @@ { while (VIM_ISDIGIT(c)) /* skip "old" count */ c = read_redo(FALSE, old_redo); - add_num_buff(&stuffbuff, count); + add_num_buff(&readbuf2, count); } /* copy from the redo buffer into the stuff buffer */ - add_char_buff(&stuffbuff, c); + add_char_buff(&readbuf2, c); copy_redo(old_redo); return OK; } /* * Repeat the last insert (R, o, O, a, A, i or I command) by stuffing - * the redo buffer into the stuffbuff. + * the redo buffer into readbuf2. * return FAIL for failure, OK otherwise */ int @@ -879,7 +916,7 @@ if (vim_strchr((char_u *)"AaIiRrOo", c) != NULL) { if (c == 'O' || c == 'o') - stuffReadbuff(NL_STR); + add_buff(&readbuf2, NL_STR, -1L); break; } } @@ -1360,8 +1397,10 @@ tp->old_mod_mask = old_mod_mask; old_char = -1; - tp->save_stuffbuff = stuffbuff; - stuffbuff.bh_first.b_next = NULL; + tp->save_readbuf1 = readbuf1; + readbuf1.bh_first.b_next = NULL; + tp->save_readbuf2 = readbuf2; + readbuf2.bh_first.b_next = NULL; # ifdef USE_INPUT_BUF tp->save_inputbuf = get_input_buf(); # endif @@ -1384,8 +1423,10 @@ old_char = tp->old_char; old_mod_mask = tp->old_mod_mask; - free_buff(&stuffbuff); - stuffbuff = tp->save_stuffbuff; + free_buff(&readbuf1); + readbuf1 = tp->save_readbuf1; + free_buff(&readbuf2); + readbuf2 = tp->save_readbuf2; # ifdef USE_INPUT_BUF set_input_buf(tp->save_inputbuf); # endif @@ -1992,7 +2033,7 @@ typeahead_char = 0; } else - c = read_stuff(advance); + c = read_readbuffers(advance); if (c != NUL && !got_int) { if (advance) @@ -2261,6 +2302,10 @@ msg_row = Rows - 1; msg_clr_eos(); /* clear ruler */ } +#ifdef FEAT_WINDOWS + status_redraw_all(); + redraw_statuslines(); +#endif showmode(); setcursor(); continue; diff -ubBwrN ../../work/vim74/src/globals.h ./src/globals.h --- ../../work/vim74/src/globals.h 2013-07-04 20:53:44.000000000 +0300 +++ ./src/globals.h 2014-02-22 19:30:45.000000000 +0300 @@ -979,11 +979,6 @@ EXTERN int readonlymode INIT(= FALSE); /* Set to TRUE for "view" */ EXTERN int recoverymode INIT(= FALSE); /* Set to TRUE for "-r" option */ -EXTERN struct buffheader stuffbuff /* stuff buffer */ -#ifdef DO_INIT - = {{NULL, {NUL}}, NULL, 0, 0} -#endif - ; EXTERN typebuf_T typebuf /* typeahead buffer */ #ifdef DO_INIT = {NULL, NULL, 0, 0, 0, 0, 0, 0, 0} @@ -1490,6 +1485,7 @@ EXTERN char_u e_notopen[] INIT(= N_("E484: Can't open file %s")); EXTERN char_u e_notread[] INIT(= N_("E485: Can't read file %s")); EXTERN char_u e_nowrtmsg[] INIT(= N_("E37: No write since last change (add ! to override)")); +EXTERN char_u e_nowrtmsg_nobang[] INIT(= N_("E37: No write since last change")); EXTERN char_u e_null[] INIT(= N_("E38: Null argument")); #ifdef FEAT_DIGRAPHS EXTERN char_u e_number_exp[] INIT(= N_("E39: Number expected")); diff -ubBwrN ../../work/vim74/src/gui_w48.c ./src/gui_w48.c --- ../../work/vim74/src/gui_w48.c 2013-08-10 14:36:45.000000000 +0300 +++ ./src/gui_w48.c 2014-02-22 19:30:40.000000000 +0300 @@ -1008,7 +1008,7 @@ static LPARAM last_lParam = 0L; /* We sometimes get a mousemove when the mouse didn't move... */ - if (uMsg == WM_MOUSEMOVE) + if (uMsg == WM_MOUSEMOVE || uMsg == WM_NCMOUSEMOVE) { if (lParam == last_lParam) return; diff -ubBwrN ../../work/vim74/src/if_perl.xs ./src/if_perl.xs --- ../../work/vim74/src/if_perl.xs 2013-08-02 20:28:50.000000000 +0300 +++ ./src/if_perl.xs 2014-02-22 19:30:44.000000000 +0300 @@ -14,7 +14,8 @@ #define IN_PERL_FILE /* don't include if_perl.pro from proto.h */ /* - * Currently 32-bit version of ActivePerl is built with VC6. + * Currently 32-bit version of ActivePerl is built with VC6 (or MinGW since + * ActivePerl 5.18). * (http://community.activestate.com/faq/windows-compilers-perl-modules) * It means that time_t should be 32-bit. However the default size of * time_t is 64-bit since VC8. So we have to define _USE_32BIT_TIME_T. @@ -23,8 +24,31 @@ # define _USE_32BIT_TIME_T #endif +/* + * Prevent including winsock.h. perl.h tries to detect whether winsock.h is + * already included before including winsock2.h, because winsock2.h isn't + * compatible with winsock.h. However the detection doesn't work with some + * versions of MinGW. If WIN32_LEAN_AND_MEAN is defined, windows.h will not + * include winsock.h. + */ +#ifdef WIN32 +# define WIN32_LEAN_AND_MEAN +#endif + #include "vim.h" +/* Work around for perl-5.18. + * Don't include "perl\lib\CORE\inline.h" for now, + * include it after Perl_sv_free2 is defined. */ +#ifdef DYNAMIC_PERL +# define PERL_NO_INLINE_FUNCTIONS +#endif + +/* Work around for using MSVC and ActivePerl 5.18. */ +#ifdef _MSC_VER +# define __inline__ __inline +#endif + #include #include #include @@ -81,10 +105,6 @@ # define PERL5101_OR_LATER #endif -#if (PERL_REVISION == 5) && (PERL_VERSION >= 18) -# define PERL5180_OR_LATER -#endif - #ifndef pTHX # define pTHX void # define pTHX_ @@ -145,11 +165,9 @@ # define perl_free dll_perl_free # define Perl_get_context dll_Perl_get_context # define Perl_croak dll_Perl_croak -# ifndef PERL5180_OR_LATER # ifdef PERL5101_OR_LATER # define Perl_croak_xs_usage dll_Perl_croak_xs_usage # endif -# endif # ifndef PROTO # define Perl_croak_nocontext dll_Perl_croak_nocontext # define Perl_call_argv dll_Perl_call_argv @@ -262,8 +280,11 @@ static int (*perl_parse)(PerlInterpreter*, XSINIT_t, int, char**, char**); static void* (*Perl_get_context)(void); static void (*Perl_croak)(pTHX_ const char*, ...); -#ifndef PERL5180_OR_LATER #ifdef PERL5101_OR_LATER +/* Perl-5.18 has a different Perl_croak_xs_usage signature. */ +# if (PERL_REVISION == 5) && (PERL_VERSION >= 18) +static void (*Perl_croak_xs_usage)(const CV *const, const char *const params); +# else static void (*Perl_croak_xs_usage)(pTHX_ const CV *const, const char *const params); #endif #endif @@ -337,7 +358,12 @@ static XPV** (*Perl_TXpv_ptr)(register PerlInterpreter*); static STRLEN* (*Perl_Tna_ptr)(register PerlInterpreter*); #else +/* Perl-5.18 has a different Perl_sv_free2 signature. */ +# if (PERL_REVISION == 5) && (PERL_VERSION >= 18) +static void (*Perl_sv_free2)(pTHX_ SV*, const U32); +# else static void (*Perl_sv_free2)(pTHX_ SV*); +# endif static void (*Perl_sys_init)(int* argc, char*** argv); static void (*Perl_sys_term)(void); static void (*Perl_call_list)(pTHX_ I32, AV*); @@ -384,11 +410,9 @@ {"perl_parse", (PERL_PROC*)&perl_parse}, {"Perl_get_context", (PERL_PROC*)&Perl_get_context}, {"Perl_croak", (PERL_PROC*)&Perl_croak}, -#ifndef PERL5180_OR_LATER #ifdef PERL5101_OR_LATER {"Perl_croak_xs_usage", (PERL_PROC*)&Perl_croak_xs_usage}, #endif -#endif {"Perl_croak_nocontext", (PERL_PROC*)&Perl_croak_nocontext}, {"Perl_dowantarray", (PERL_PROC*)&Perl_dowantarray}, {"Perl_free_tmps", (PERL_PROC*)&Perl_free_tmps}, @@ -492,6 +516,14 @@ {"", NULL}, }; +/* Work around for perl-5.18. + * The definitions of S_SvREFCNT_inc and S_SvREFCNT_dec are needed, so include + * "perl\lib\CORE\inline.h", after Perl_sv_free2 is defined. + * The linker won't complain about undefined __impl_Perl_sv_free2. */ +#if (PERL_REVISION == 5) && (PERL_VERSION >= 18) +# include +#endif + /* * Make all runtime-links of perl. * diff -ubBwrN ../../work/vim74/src/if_py_both.h ./src/if_py_both.h --- ../../work/vim74/src/if_py_both.h 2013-07-24 18:09:19.000000000 +0300 +++ ./src/if_py_both.h 2014-02-22 19:30:46.000000000 +0300 @@ -13,6 +13,11 @@ * Common code for if_python.c and if_python3.c. */ +#ifdef __BORLANDC__ +/* Disable Warning W8060: Possibly incorrect assignment in function ... */ +# pragma warn -8060 +#endif + static char_u e_py_systemexit[] = "E880: Can't handle SystemExit of %s exception in vim"; #if PY_VERSION_HEX < 0x02050000 @@ -31,8 +36,9 @@ #define PyErr_SET_STRING(exc, str) PyErr_SetString(exc, _(str)) #define PyErr_SetVim(str) PyErr_SetString(VimError, str) #define PyErr_SET_VIM(str) PyErr_SET_STRING(VimError, str) -#define PyErr_FORMAT(exc, str, tail) PyErr_Format(exc, _(str), tail) -#define PyErr_VIM_FORMAT(str, tail) PyErr_FORMAT(VimError, str, tail) +#define PyErr_FORMAT(exc, str, arg) PyErr_Format(exc, _(str), arg) +#define PyErr_FORMAT2(exc, str, arg1, arg2) PyErr_Format(exc, _(str), arg1,arg2) +#define PyErr_VIM_FORMAT(str, arg) PyErr_FORMAT(VimError, str, arg) #define Py_TYPE_NAME(obj) (obj->ob_type->tp_name == NULL \ ? "(NULL)" \ @@ -558,16 +564,40 @@ /* Keyboard interrupt should be preferred over anything else */ if (got_int) { - did_throw = got_int = FALSE; + if (did_throw) + discard_current_exception(); + got_int = FALSE; PyErr_SetNone(PyExc_KeyboardInterrupt); return -1; } + else if (msg_list != NULL && *msg_list != NULL) + { + int should_free; + char_u *msg; + + msg = get_exception_string(*msg_list, ET_ERROR, NULL, &should_free); + + if (msg == NULL) + { + PyErr_NoMemory(); + return -1; + } + + PyErr_SetVim((char *) msg); + + free_global_msglist(); + + if (should_free) + vim_free(msg); + + return -1; + } else if (!did_throw) return (PyErr_Occurred() ? -1 : 0); /* Python exception is preferred over vim one; unlikely to occur though */ else if (PyErr_Occurred()) { - did_throw = FALSE; + discard_current_exception(); return -1; } /* Finally transform VimL exception to python one */ @@ -1587,8 +1617,9 @@ } else if (flags & DICT_FLAG_RETURN_BOOL) { - Py_INCREF(Py_True); - return Py_True; + ret = Py_True; + Py_INCREF(ret); + return ret; } di = dict_lookup(hi); @@ -1624,6 +1655,9 @@ PyObject *rObj = _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL); int ret; + if (rObj == NULL) + return -1; + ret = (rObj == Py_True); Py_DECREF(rObj); @@ -1885,11 +1919,17 @@ } else { - PyObject *obj; + PyObject *obj = NULL; - if (!PyArg_ParseTuple(args, "O", &obj)) + if (!PyArg_ParseTuple(args, "|O", &obj)) return NULL; + if (obj == NULL) + { + Py_INCREF(Py_None); + return Py_None; + } + if (PyObject_HasAttrString(obj, "keys")) return DictionaryUpdate(self, NULL, obj); else @@ -2071,8 +2111,6 @@ }; static PyTypeObject ListType; -static PySequenceMethods ListAsSeq; -static PyMappingMethods ListAsMapping; typedef struct { @@ -2216,7 +2254,7 @@ } static PyObject * -ListItem(ListObject *self, Py_ssize_t index) +ListIndex(ListObject *self, Py_ssize_t index) { listitem_T *li; @@ -2236,173 +2274,154 @@ return ConvertToPyObject(&li->li_tv); } -#define PROC_RANGE \ - if (last < 0) {\ - if (last < -size) \ - last = 0; \ - else \ - last += size; \ - } \ - if (first < 0) \ - first = 0; \ - if (first > size) \ - first = size; \ - if (last > size) \ - last = size; - static PyObject * -ListSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last) +ListSlice(ListObject *self, Py_ssize_t first, Py_ssize_t step, + Py_ssize_t slicelen) { PyInt i; - PyInt size = ListLength(self); - PyInt n; PyObject *list; - int reversed = 0; - PROC_RANGE - if (first >= last) - first = last; + if (step == 0) + { + PyErr_SET_STRING(PyExc_ValueError, N_("slice step cannot be zero")); + return NULL; + } - n = last-first; - list = PyList_New(n); + list = PyList_New(slicelen); if (list == NULL) return NULL; - for (i = 0; i < n; ++i) + for (i = 0; i < slicelen; ++i) { - PyObject *item = ListItem(self, first + i); + PyObject *item; + + item = ListIndex(self, first + i*step); if (item == NULL) { Py_DECREF(list); return NULL; } - PyList_SET_ITEM(list, ((reversed)?(n-i-1):(i)), item); + PyList_SET_ITEM(list, i, item); } return list; } -typedef struct + static PyObject * +ListItem(ListObject *self, PyObject* idx) { - listwatch_T lw; - list_T *list; -} listiterinfo_T; - - static void -ListIterDestruct(listiterinfo_T *lii) +#if PY_MAJOR_VERSION < 3 + if (PyInt_Check(idx)) { - list_rem_watch(lii->list, &lii->lw); - PyMem_Free(lii); + long _idx = PyInt_AsLong(idx); + return ListIndex(self, _idx); } - - static PyObject * -ListIterNext(listiterinfo_T **lii) + else +#endif + if (PyLong_Check(idx)) { - PyObject *ret; + long _idx = PyLong_AsLong(idx); + return ListIndex(self, _idx); + } + else if (PySlice_Check(idx)) + { + Py_ssize_t start, stop, step, slicelen; - if (!((*lii)->lw.lw_item)) + if (PySlice_GetIndicesEx((PySliceObject *)idx, ListLength(self), + &start, &stop, &step, &slicelen) < 0) return NULL; - - if (!(ret = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv)))) + return ListSlice(self, start, step, slicelen); + } + else + { + RAISE_INVALID_INDEX_TYPE(idx); return NULL; - - (*lii)->lw.lw_item = (*lii)->lw.lw_item->li_next; - - return ret; + } } - static PyObject * -ListIter(ListObject *self) + static void +list_restore(Py_ssize_t numadded, Py_ssize_t numreplaced, Py_ssize_t slicelen, + list_T *l, listitem_T **lis, listitem_T *lastaddedli) { - listiterinfo_T *lii; - list_T *l = self->list; - - if (!(lii = PyMem_New(listiterinfo_T, 1))) + while (numreplaced--) { - PyErr_NoMemory(); - return NULL; + list_insert(l, lis[numreplaced], lis[slicelen + numreplaced]); + listitem_remove(l, lis[slicelen + numreplaced]); } + while (numadded--) + { + listitem_T *next; - list_add_watch(l, &lii->lw); - lii->lw.lw_item = l->lv_first; - lii->list = l; - - return IterNew(lii, - (destructorfun) ListIterDestruct, (nextfun) ListIterNext, - NULL, NULL); + next = lastaddedli->li_prev; + listitem_remove(l, lastaddedli); + lastaddedli = next; + } } static int -ListAssItem(ListObject *self, Py_ssize_t index, PyObject *obj) +ListAssSlice(ListObject *self, Py_ssize_t first, + Py_ssize_t step, Py_ssize_t slicelen, PyObject *obj) { - typval_T tv; - list_T *l = self->list; + PyObject *iterator; + PyObject *item; listitem_T *li; - Py_ssize_t length = ListLength(self); + listitem_T *lastaddedli = NULL; + listitem_T *next; + typval_T v; + list_T *l = self->list; + PyInt i; + PyInt j; + PyInt numreplaced = 0; + PyInt numadded = 0; + PyInt size; + listitem_T **lis = NULL; + + size = ListLength(self); if (l->lv_lock) { RAISE_LOCKED_LIST; return -1; } - if (index > length || (index == length && obj == NULL)) + + if (step == 0) { - PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range")); + PyErr_SET_STRING(PyExc_ValueError, N_("slice step cannot be zero")); return -1; } - if (obj == NULL) + if (step != 1 && slicelen == 0) { - li = list_find(l, (long) index); - list_remove(l, li, li); - clear_tv(&li->li_tv); - vim_free(li); + /* Nothing to do. Only error out if obj has some items. */ + int ret = 0; + + if (obj == NULL) return 0; - } - if (ConvertFromPyObject(obj, &tv) == -1) + if (!(iterator = PyObject_GetIter(obj))) return -1; - if (index == length) - { - if (list_append_tv(l, &tv) == FAIL) + if ((item = PyIter_Next(iterator))) { - clear_tv(&tv); - PyErr_SET_VIM(N_("failed to add item to list")); - return -1; - } - } - else - { - li = list_find(l, (long) index); - clear_tv(&li->li_tv); - copy_tv(&tv, &li->li_tv); - clear_tv(&tv); + PyErr_FORMAT(PyExc_ValueError, + N_("attempt to assign sequence of size greater then %d " + "to extended slice"), 0); + Py_DECREF(item); + ret = -1; } - return 0; + Py_DECREF(iterator); + return ret; } - static int -ListAssSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj) -{ - PyInt size = ListLength(self); - PyObject *iterator; - PyObject *item; - listitem_T *li; - listitem_T *next; - typval_T v; - list_T *l = self->list; - PyInt i; - - if (l->lv_lock) + if (obj != NULL) + /* XXX May allocate zero bytes. */ + if (!(lis = PyMem_New(listitem_T *, slicelen * 2))) { - RAISE_LOCKED_LIST; + PyErr_NoMemory(); return -1; } - PROC_RANGE - if (first == size) li = NULL; else @@ -2412,17 +2431,33 @@ { PyErr_VIM_FORMAT(N_("internal error: no vim list item %d"), (int)first); + if (obj != NULL) + PyMem_Free(lis); return -1; } - if (last > first) - { - i = last - first; + i = slicelen; while (i-- && li != NULL) { - next = li->li_next; + j = step; + next = li; + if (step > 0) + while (next != NULL && ((next = next->li_next) != NULL) && --j); + else + while (next != NULL && ((next = next->li_prev) != NULL) && ++j); + + if (obj == NULL) listitem_remove(l, li); + else + lis[slicelen - i - 1] = li; + li = next; } + if (li == NULL && i != -1) + { + PyErr_SET_VIM(N_("internal error: not enough list items")); + if (obj != NULL) + PyMem_Free(lis); + return -1; } } @@ -2430,33 +2465,172 @@ return 0; if (!(iterator = PyObject_GetIter(obj))) + { + PyMem_Free(lis); return -1; + } + i = 0; while ((item = PyIter_Next(iterator))) { if (ConvertFromPyObject(item, &v) == -1) { Py_DECREF(iterator); Py_DECREF(item); + PyMem_Free(lis); return -1; } Py_DECREF(item); - if (list_insert_tv(l, &v, li) == FAIL) + if (list_insert_tv(l, &v, numreplaced < slicelen + ? lis[numreplaced] + : li) == FAIL) { clear_tv(&v); PyErr_SET_VIM(N_("internal error: failed to add item to list")); + list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli); + PyMem_Free(lis); return -1; } + if (numreplaced < slicelen) + { + lis[slicelen + numreplaced] = lis[numreplaced]->li_prev; + list_remove(l, lis[numreplaced], lis[numreplaced]); + numreplaced++; + } + else + { + if (li) + lastaddedli = li->li_prev; + else + lastaddedli = l->lv_last; + numadded++; + } clear_tv(&v); + if (step != 1 && i >= slicelen) + { + Py_DECREF(iterator); + PyErr_FORMAT(PyExc_ValueError, + N_("attempt to assign sequence of size greater then %d " + "to extended slice"), (int) slicelen); + list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli); + PyMem_Free(lis); + return -1; + } + ++i; } Py_DECREF(iterator); + if (step != 1 && i != slicelen) + { + PyErr_FORMAT2(PyExc_ValueError, + N_("attempt to assign sequence of size %d to extended slice " + "of size %d"), (int) i, (int) slicelen); + list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli); + PyMem_Free(lis); + return -1; + } + if (PyErr_Occurred()) + { + list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli); + PyMem_Free(lis); return -1; + } + + for (i = 0; i < numreplaced; i++) + listitem_free(lis[i]); + if (step == 1) + for (i = numreplaced; i < slicelen; i++) + listitem_remove(l, lis[i]); + + PyMem_Free(lis); return 0; } + static int +ListAssIndex(ListObject *self, Py_ssize_t index, PyObject *obj) +{ + typval_T tv; + list_T *l = self->list; + listitem_T *li; + Py_ssize_t length = ListLength(self); + + if (l->lv_lock) + { + RAISE_LOCKED_LIST; + return -1; + } + if (index > length || (index == length && obj == NULL)) + { + PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range")); + return -1; + } + + if (obj == NULL) + { + li = list_find(l, (long) index); + list_remove(l, li, li); + clear_tv(&li->li_tv); + vim_free(li); + return 0; + } + + if (ConvertFromPyObject(obj, &tv) == -1) + return -1; + + if (index == length) + { + if (list_append_tv(l, &tv) == FAIL) + { + clear_tv(&tv); + PyErr_SET_VIM(N_("failed to add item to list")); + return -1; + } + } + else + { + li = list_find(l, (long) index); + clear_tv(&li->li_tv); + copy_tv(&tv, &li->li_tv); + clear_tv(&tv); + } + return 0; +} + + static Py_ssize_t +ListAssItem(ListObject *self, PyObject *idx, PyObject *obj) +{ +#if PY_MAJOR_VERSION < 3 + if (PyInt_Check(idx)) + { + long _idx = PyInt_AsLong(idx); + return ListAssIndex(self, _idx, obj); + } + else +#endif + if (PyLong_Check(idx)) + { + long _idx = PyLong_AsLong(idx); + return ListAssIndex(self, _idx, obj); + } + else if (PySlice_Check(idx)) + { + Py_ssize_t start, stop, step, slicelen; + + if (PySlice_GetIndicesEx((PySliceObject *)idx, ListLength(self), + &start, &stop, &step, &slicelen) < 0) + return -1; + return ListAssSlice(self, start, step, slicelen, + obj); + } + else + { + RAISE_INVALID_INDEX_TYPE(idx); + return -1; + } +} + static PyObject * ListConcatInPlace(ListObject *self, PyObject *obj) { @@ -2483,6 +2657,56 @@ return (PyObject *)(self); } +typedef struct +{ + listwatch_T lw; + list_T *list; +} listiterinfo_T; + + static void +ListIterDestruct(listiterinfo_T *lii) +{ + list_rem_watch(lii->list, &lii->lw); + PyMem_Free(lii); +} + + static PyObject * +ListIterNext(listiterinfo_T **lii) +{ + PyObject *ret; + + if (!((*lii)->lw.lw_item)) + return NULL; + + if (!(ret = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv)))) + return NULL; + + (*lii)->lw.lw_item = (*lii)->lw.lw_item->li_next; + + return ret; +} + + static PyObject * +ListIter(ListObject *self) +{ + listiterinfo_T *lii; + list_T *l = self->list; + + if (!(lii = PyMem_New(listiterinfo_T, 1))) + { + PyErr_NoMemory(); + return NULL; + } + + list_add_watch(l, &lii->lw); + lii->lw.lw_item = l->lv_first; + lii->list = l; + + return IterNew(lii, + (destructorfun) ListIterDestruct, (nextfun) ListIterNext, + NULL, NULL); +} + static char *ListAttrs[] = { "locked", NULL @@ -2530,6 +2754,25 @@ } } +static PySequenceMethods ListAsSeq = { + (lenfunc) ListLength, /* sq_length, len(x) */ + (binaryfunc) 0, /* RangeConcat, sq_concat, x+y */ + 0, /* RangeRepeat, sq_repeat, x*n */ + (PyIntArgFunc) ListIndex, /* sq_item, x[i] */ + 0, /* was_sq_slice, x[i:j] */ + (PyIntObjArgProc) ListAssIndex, /* sq_as_item, x[i]=v */ + 0, /* was_sq_ass_slice, x[i:j]=v */ + 0, /* sq_contains */ + (binaryfunc) ListConcatInPlace,/* sq_inplace_concat */ + 0, /* sq_inplace_repeat */ +}; + +static PyMappingMethods ListAsMapping = { + /* mp_length */ (lenfunc) ListLength, + /* mp_subscript */ (binaryfunc) ListItem, + /* mp_ass_subscript */ (objobjargproc) ListAssItem, +}; + static struct PyMethodDef ListMethods[] = { {"extend", (PyCFunction)ListConcatInPlace, METH_O, ""}, {"__dir__", (PyCFunction)ListDir, METH_NOARGS, ""}, @@ -2831,6 +3074,69 @@ } static int +OptionsContains(OptionsObject *self, PyObject *keyObject) +{ + char_u *key; + PyObject *todecref; + + if (!(key = StringToChars(keyObject, &todecref))) + return -1; + + if (*key == NUL) + { + Py_XDECREF(todecref); + return 0; + } + + if (get_option_value_strict(key, NULL, NULL, self->opt_type, NULL)) + { + Py_XDECREF(todecref); + return 1; + } + else + { + Py_XDECREF(todecref); + return 0; + } +} + +typedef struct +{ + void *lastoption; + int opt_type; +} optiterinfo_T; + + static PyObject * +OptionsIterNext(optiterinfo_T **oii) +{ + char_u *name; + + if ((name = option_iter_next(&((*oii)->lastoption), (*oii)->opt_type))) + return PyString_FromString((char *)name); + + return NULL; +} + + static PyObject * +OptionsIter(OptionsObject *self) +{ + optiterinfo_T *oii; + + if (!(oii = PyMem_New(optiterinfo_T, 1))) + { + PyErr_NoMemory(); + return NULL; + } + + oii->opt_type = self->opt_type; + oii->lastoption = NULL; + + return IterNew(oii, + (destructorfun) PyMem_Free, (nextfun) OptionsIterNext, + NULL, NULL); +} + + static int set_option_value_err(char_u *key, int numval, char_u *stringval, int opt_flags) { char_u *errmsg; @@ -2973,11 +3279,14 @@ else { char_u *val; - PyObject *todecref; + PyObject *todecref2; - if ((val = StringToChars(valObject, &todecref))) + if ((val = StringToChars(valObject, &todecref2))) + { ret = set_option_value_for(key, 0, val, opt_flags, self->opt_type, self->from); + Py_XDECREF(todecref2); + } else ret = -1; } @@ -2987,6 +3296,19 @@ return ret; } +static PySequenceMethods OptionsAsSeq = { + 0, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + 0, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + (objobjproc) OptionsContains, /* sq_contains */ + 0, /* sq_inplace_concat */ + 0, /* sq_inplace_repeat */ +}; + static PyMappingMethods OptionsAsMapping = { (lenfunc) NULL, (binaryfunc) OptionsItem, @@ -5877,8 +6199,10 @@ vim_memset(&OptionsType, 0, sizeof(OptionsType)); OptionsType.tp_name = "vim.options"; OptionsType.tp_basicsize = sizeof(OptionsObject); + OptionsType.tp_as_sequence = &OptionsAsSeq; OptionsType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC; OptionsType.tp_doc = "object for manipulating options"; + OptionsType.tp_iter = (getiterfunc)OptionsIter; OptionsType.tp_as_mapping = &OptionsAsMapping; OptionsType.tp_dealloc = (destructor)OptionsDestructor; OptionsType.tp_traverse = (traverseproc)OptionsTraverse; diff -ubBwrN ../../work/vim74/src/if_python.c ./src/if_python.c --- ../../work/vim74/src/if_python.c 2013-07-09 22:40:11.000000000 +0300 +++ ./src/if_python.c 2014-02-22 19:30:45.000000000 +0300 @@ -196,6 +196,7 @@ # define PyTuple_Size dll_PyTuple_Size # define PyTuple_GetItem dll_PyTuple_GetItem # define PyTuple_Type (*dll_PyTuple_Type) +# define PySlice_GetIndicesEx dll_PySlice_GetIndicesEx # define PyImport_ImportModule dll_PyImport_ImportModule # define PyDict_New dll_PyDict_New # define PyDict_GetItemString dll_PyDict_GetItemString @@ -241,6 +242,7 @@ # define PySys_GetObject dll_PySys_GetObject # define PySys_SetArgv dll_PySys_SetArgv # define PyType_Type (*dll_PyType_Type) +# define PySlice_Type (*dll_PySlice_Type) # define PyType_Ready (*dll_PyType_Ready) # define PyType_GenericAlloc dll_PyType_GenericAlloc # define Py_BuildValue dll_Py_BuildValue @@ -341,6 +343,9 @@ static PyInt(*dll_PyTuple_Size)(PyObject *); static PyObject*(*dll_PyTuple_GetItem)(PyObject *, PyInt); static PyTypeObject* dll_PyTuple_Type; +static int (*dll_PySlice_GetIndicesEx)(PySliceObject *r, PyInt length, + PyInt *start, PyInt *stop, PyInt *step, + PyInt *slicelen); static PyObject*(*dll_PyImport_ImportModule)(const char *); static PyObject*(*dll_PyDict_New)(void); static PyObject*(*dll_PyDict_GetItemString)(PyObject *, const char *); @@ -359,7 +364,7 @@ static PyObject *(*dll_PyRun_String)(char *, int, PyObject *, PyObject *); static PyObject* (*dll_PyObject_GetAttrString)(PyObject *, const char *); static int (*dll_PyObject_HasAttrString)(PyObject *, const char *); -static PyObject* (*dll_PyObject_SetAttrString)(PyObject *, const char *, PyObject *); +static int (*dll_PyObject_SetAttrString)(PyObject *, const char *, PyObject *); static PyObject* (*dll_PyObject_CallFunctionObjArgs)(PyObject *, ...); static PyObject* (*dll_PyObject_CallFunction)(PyObject *, char *, ...); static PyObject* (*dll_PyObject_Call)(PyObject *, PyObject *, PyObject *); @@ -382,6 +387,7 @@ static PyObject *(*dll_PySys_GetObject)(char *); static int(*dll_PySys_SetArgv)(int, char **); static PyTypeObject* dll_PyType_Type; +static PyTypeObject* dll_PySlice_Type; static int (*dll_PyType_Ready)(PyTypeObject *type); static PyObject* (*dll_PyType_GenericAlloc)(PyTypeObject *type, PyInt nitems); static PyObject*(*dll_Py_BuildValue)(char *, ...); @@ -521,6 +527,7 @@ {"PyTuple_GetItem", (PYTHON_PROC*)&dll_PyTuple_GetItem}, {"PyTuple_Size", (PYTHON_PROC*)&dll_PyTuple_Size}, {"PyTuple_Type", (PYTHON_PROC*)&dll_PyTuple_Type}, + {"PySlice_GetIndicesEx", (PYTHON_PROC*)&dll_PySlice_GetIndicesEx}, {"PyImport_ImportModule", (PYTHON_PROC*)&dll_PyImport_ImportModule}, {"PyDict_GetItemString", (PYTHON_PROC*)&dll_PyDict_GetItemString}, {"PyDict_Next", (PYTHON_PROC*)&dll_PyDict_Next}, @@ -562,6 +569,7 @@ {"PySys_GetObject", (PYTHON_PROC*)&dll_PySys_GetObject}, {"PySys_SetArgv", (PYTHON_PROC*)&dll_PySys_SetArgv}, {"PyType_Type", (PYTHON_PROC*)&dll_PyType_Type}, + {"PySlice_Type", (PYTHON_PROC*)&dll_PySlice_Type}, {"PyType_Ready", (PYTHON_PROC*)&dll_PyType_Ready}, {"PyType_GenericAlloc", (PYTHON_PROC*)&dll_PyType_GenericAlloc}, {"Py_FindMethod", (PYTHON_PROC*)&dll_Py_FindMethod}, @@ -1472,21 +1480,6 @@ return Py_FindMethod(DictionaryMethods, self, name); } -static PySequenceMethods ListAsSeq = { - (PyInquiry) ListLength, - (binaryfunc) 0, - (PyIntArgFunc) 0, - (PyIntArgFunc) ListItem, - (PyIntIntArgFunc) ListSlice, - (PyIntObjArgProc) ListAssItem, - (PyIntIntObjArgProc) ListAssSlice, - (objobjproc) 0, -#if PY_MAJOR_VERSION >= 2 - (binaryfunc) ListConcatInPlace, - 0, -#endif -}; - static PyObject * ListGetattr(PyObject *self, char *name) { diff -ubBwrN ../../work/vim74/src/if_python3.c ./src/if_python3.c --- ../../work/vim74/src/if_python3.c 2013-07-09 22:53:21.000000000 +0300 +++ ./src/if_python3.c 2014-02-22 19:30:45.000000000 +0300 @@ -97,6 +97,9 @@ #define Py_ssize_t_fmt "n" #define Py_bytes_fmt "y" +#define PyIntArgFunc ssizeargfunc +#define PyIntObjArgProc ssizeobjargproc + #if defined(DYNAMIC_PYTHON3) || defined(PROTO) # ifndef WIN3264 @@ -291,8 +294,9 @@ static PyObject* (*py3_PyTuple_GetItem)(PyObject *, Py_ssize_t); static int (*py3_PyMapping_Check)(PyObject *); static PyObject* (*py3_PyMapping_Keys)(PyObject *); -static int (*py3_PySlice_GetIndicesEx)(PyObject *r, Py_ssize_t length, - Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength); +static int (*py3_PySlice_GetIndicesEx)(PySliceObject *r, Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, + Py_ssize_t *slicelen); static PyObject* (*py3_PyErr_NoMemory)(void); static void (*py3_Py_Finalize)(void); static void (*py3_PyErr_SetString)(PyObject *, const char *); @@ -302,7 +306,7 @@ static PyObject* (*py3_PyRun_String)(char *, int, PyObject *, PyObject *); static PyObject* (*py3_PyObject_GetAttrString)(PyObject *, const char *); static int (*py3_PyObject_HasAttrString)(PyObject *, const char *); -static PyObject* (*py3_PyObject_SetAttrString)(PyObject *, const char *, PyObject *); +static int (*py3_PyObject_SetAttrString)(PyObject *, const char *, PyObject *); static PyObject* (*py3_PyObject_CallFunctionObjArgs)(PyObject *, ...); static PyObject* (*py3__PyObject_CallFunction_SizeT)(PyObject *, char *, ...); static PyObject* (*py3_PyObject_Call)(PyObject *, PyObject *, PyObject *); @@ -1186,7 +1190,7 @@ if (CheckBuffer((BufferObject *) self)) return NULL; - if (PySlice_GetIndicesEx((PyObject *)idx, + if (PySlice_GetIndicesEx((PySliceObject *)idx, (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count, &start, &stop, &step, &slicelen) < 0) @@ -1218,7 +1222,7 @@ if (CheckBuffer((BufferObject *) self)) return -1; - if (PySlice_GetIndicesEx((PyObject *)idx, + if (PySlice_GetIndicesEx((PySliceObject *)idx, (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count, &start, &stop, &step, &slicelen) < 0) @@ -1302,7 +1306,7 @@ { Py_ssize_t start, stop, step, slicelen; - if (PySlice_GetIndicesEx((PyObject *)idx, + if (PySlice_GetIndicesEx((PySliceObject *)idx, ((RangeObject *)(self))->end-((RangeObject *)(self))->start+1, &start, &stop, &step, &slicelen) < 0) @@ -1329,7 +1333,7 @@ { Py_ssize_t start, stop, step, slicelen; - if (PySlice_GetIndicesEx((PyObject *)idx, + if (PySlice_GetIndicesEx((PySliceObject *)idx, ((RangeObject *)(self))->end-((RangeObject *)(self))->start+1, &start, &stop, &step, &slicelen) < 0) @@ -1478,76 +1482,6 @@ /* List object - Definitions */ -static PySequenceMethods ListAsSeq = { - (lenfunc) ListLength, /* sq_length, len(x) */ - (binaryfunc) 0, /* RangeConcat, sq_concat, x+y */ - (ssizeargfunc) 0, /* RangeRepeat, sq_repeat, x*n */ - (ssizeargfunc) ListItem, /* sq_item, x[i] */ - (void *) 0, /* was_sq_slice, x[i:j] */ - (ssizeobjargproc) ListAssItem, /* sq_as_item, x[i]=v */ - (void *) 0, /* was_sq_ass_slice, x[i:j]=v */ - 0, /* sq_contains */ - (binaryfunc) ListConcatInPlace,/* sq_inplace_concat */ - 0, /* sq_inplace_repeat */ -}; - -static PyObject *ListSubscript(PyObject *, PyObject *); -static Py_ssize_t ListAsSubscript(PyObject *, PyObject *, PyObject *); - -static PyMappingMethods ListAsMapping = { - /* mp_length */ (lenfunc) ListLength, - /* mp_subscript */ (binaryfunc) ListSubscript, - /* mp_ass_subscript */ (objobjargproc) ListAsSubscript, -}; - - static PyObject * -ListSubscript(PyObject *self, PyObject* idx) -{ - if (PyLong_Check(idx)) - { - long _idx = PyLong_AsLong(idx); - return ListItem((ListObject *)(self), _idx); - } - else if (PySlice_Check(idx)) - { - Py_ssize_t start, stop, step, slicelen; - - if (PySlice_GetIndicesEx(idx, ListLength((ListObject *)(self)), - &start, &stop, &step, &slicelen) < 0) - return NULL; - return ListSlice((ListObject *)(self), start, stop); - } - else - { - RAISE_INVALID_INDEX_TYPE(idx); - return NULL; - } -} - - static Py_ssize_t -ListAsSubscript(PyObject *self, PyObject *idx, PyObject *obj) -{ - if (PyLong_Check(idx)) - { - long _idx = PyLong_AsLong(idx); - return ListAssItem((ListObject *)(self), _idx, obj); - } - else if (PySlice_Check(idx)) - { - Py_ssize_t start, stop, step, slicelen; - - if (PySlice_GetIndicesEx(idx, ListLength((ListObject *)(self)), - &start, &stop, &step, &slicelen) < 0) - return -1; - return ListAssSlice((ListObject *)(self), start, stop, obj); - } - else - { - RAISE_INVALID_INDEX_TYPE(idx); - return -1; - } -} - static PyObject * ListGetattro(PyObject *self, PyObject *nameobj) { diff -ubBwrN ../../work/vim74/src/if_ruby.c ./src/if_ruby.c --- ../../work/vim74/src/if_ruby.c 2013-05-20 13:47:48.000000000 +0300 +++ ./src/if_ruby.c 2014-02-22 19:30:45.000000000 +0300 @@ -96,6 +96,12 @@ # define rb_num2int rb_num2int_stub #endif +# if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 21 +/* Ruby 2.1 adds new GC called RGenGC and RARRAY_PTR uses + * rb_gc_writebarrier_unprotect_promoted if USE_RGENGC */ +# define rb_gc_writebarrier_unprotect_promoted rb_gc_writebarrier_unprotect_promoted_stub +# endif + #include #ifdef RUBY19_OR_LATER # include @@ -373,6 +379,10 @@ static void* (*ruby_process_options)(int, char**); # endif +# if defined(USE_RGENGC) && USE_RGENGC +static void (*dll_rb_gc_writebarrier_unprotect_promoted)(VALUE); +# endif + # if defined(RUBY19_OR_LATER) && !defined(PROTO) SIGNED_VALUE rb_num2long_stub(VALUE x) { @@ -406,6 +416,13 @@ # endif # endif +# if defined(USE_RGENGC) && USE_RGENGC +void rb_gc_writebarrier_unprotect_promoted_stub(VALUE obj) +{ + return dll_rb_gc_writebarrier_unprotect_promoted(obj); +} +# endif + static HINSTANCE hinstRuby = NULL; /* Instance of ruby.dll */ /* @@ -521,6 +538,9 @@ # endif {"ruby_init_stack", (RUBY_PROC*)&dll_ruby_init_stack}, # endif +# if defined(USE_RGENGC) && USE_RGENGC + {"rb_gc_writebarrier_unprotect_promoted", (RUBY_PROC*)&dll_rb_gc_writebarrier_unprotect_promoted}, +# endif {"", NULL}, }; diff -ubBwrN ../../work/vim74/src/if_tcl.c ./src/if_tcl.c --- ../../work/vim74/src/if_tcl.c 2013-08-02 20:31:15.000000000 +0300 +++ ./src/if_tcl.c 2014-02-22 19:30:41.000000000 +0300 @@ -165,6 +165,7 @@ */ 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 @@ 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_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 -ubBwrN ../../work/vim74/src/main.c ./src/main.c --- ../../work/vim74/src/main.c 2013-07-03 13:36:49.000000000 +0300 +++ ./src/main.c 2014-02-22 19:30:44.000000000 +0300 @@ -702,6 +702,11 @@ TIME_MSG("reading viminfo"); } #endif +#ifdef FEAT_EVAL + /* It's better to make v:oldfiles an empty list than NULL. */ + if (get_vim_var_list(VV_OLDFILES) == NULL) + set_vim_var_list(VV_OLDFILES, list_alloc()); +#endif #ifdef FEAT_QUICKFIX /* @@ -812,7 +817,7 @@ 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 @@ -1048,7 +1053,7 @@ /* Setup to catch a terminating error from the X server. Just ignore * it, restore the state and continue. This might not always work * properly, but at least we don't exit unexpectedly when the X server - * exists while Vim is running in a console. */ + * exits while Vim is running in a console. */ if (!cmdwin && !noexmode && SETJMP(x_jump_env)) { State = NORMAL; @@ -2727,6 +2732,7 @@ int arg_idx; /* index in argument list */ int i; int advance = TRUE; + win_T *win; # ifdef FEAT_AUTOCMD /* @@ -2816,24 +2822,22 @@ # ifdef FEAT_AUTOCMD --autocmd_no_enter; # endif + + /* make the first window the current window */ + win = firstwin; #if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX) - /* - * Avoid making a preview window the current window. - */ - if (firstwin->w_p_pvw) + /* Avoid making a preview window the current window. */ + while (win->w_p_pvw) { - win_T *win; - - for (win = firstwin; win != NULL; win = win->w_next) - if (!win->w_p_pvw) + win = win->w_next; + if (win == NULL) { - firstwin = win; + win = firstwin; break; } } #endif - /* make the first window the current window */ - win_enter(firstwin, FALSE); + win_enter(win, FALSE); # ifdef FEAT_AUTOCMD --autocmd_no_leave; diff -ubBwrN ../../work/vim74/src/mark.c ./src/mark.c --- ../../work/vim74/src/mark.c 2013-08-02 18:22:10.000000000 +0300 +++ ./src/mark.c 2014-02-22 19:30:41.000000000 +0300 @@ -1374,6 +1374,7 @@ set_last_cursor(win) win_T *win; { + if (win->w_buffer != NULL) win->w_buffer->b_last_cursor = win->w_cursor; } diff -ubBwrN ../../work/vim74/src/mbyte.c ./src/mbyte.c --- ../../work/vim74/src/mbyte.c 2013-07-05 21:07:21.000000000 +0300 +++ ./src/mbyte.c 2014-02-22 19:30:44.000000000 +0300 @@ -83,10 +83,18 @@ # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif +# if defined(FEAT_GUI) || defined(FEAT_XCLIPBOARD) +# include +# define WINBYTE wBYTE +# else # include +# define WINBYTE BYTE +# endif # ifdef WIN32 # undef WIN32 /* Some windows.h define WIN32, we don't want that here. */ # endif +#else +# define WINBYTE BYTE #endif #if (defined(WIN3264) || defined(WIN32UNIX)) && !defined(__MINGW32__) @@ -698,7 +706,7 @@ /* enc_dbcs is set by setting 'fileencoding'. It becomes a Windows * CodePage identifier, which we can pass directly in to Windows * API */ - n = IsDBCSLeadByteEx(enc_dbcs, (BYTE)i) ? 2 : 1; + n = IsDBCSLeadByteEx(enc_dbcs, (WINBYTE)i) ? 2 : 1; #else # if defined(MACOS) || defined(__amigaos4__) /* @@ -947,8 +955,8 @@ { case 0x2121: /* ZENKAKU space */ return 0; - case 0x2122: /* KU-TEN (Japanese comma) */ - case 0x2123: /* TOU-TEN (Japanese period) */ + case 0x2122: /* TOU-TEN (Japanese comma) */ + case 0x2123: /* KU-TEN (Japanese period) */ case 0x2124: /* ZENKAKU comma */ case 0x2125: /* ZENKAKU period */ return 1; @@ -2477,9 +2485,9 @@ /* sorted list of non-overlapping intervals */ static struct clinterval { - unsigned short first; - unsigned short last; - unsigned short class; + unsigned int first; + unsigned int last; + unsigned int class; } classes[] = { {0x037e, 0x037e, 1}, /* Greek question mark */ @@ -2544,6 +2552,10 @@ {0xff1a, 0xff20, 1}, /* half/fullwidth ASCII */ {0xff3b, 0xff40, 1}, /* half/fullwidth ASCII */ {0xff5b, 0xff65, 1}, /* half/fullwidth ASCII */ + {0x20000, 0x2a6df, 0x4e00}, /* CJK Ideographs */ + {0x2a700, 0x2b73f, 0x4e00}, /* CJK Ideographs */ + {0x2b740, 0x2b81f, 0x4e00}, /* CJK Ideographs */ + {0x2f800, 0x2fa1f, 0x4e00}, /* CJK Ideographs */ }; int bot = 0; int top = sizeof(classes) / sizeof(struct clinterval) - 1; @@ -2563,9 +2575,9 @@ while (top >= bot) { mid = (bot + top) / 2; - if (classes[mid].last < c) + if (classes[mid].last < (unsigned int)c) bot = mid + 1; - else if (classes[mid].first > c) + else if (classes[mid].first > (unsigned int)c) top = mid - 1; else return (int)classes[mid].class; diff -ubBwrN ../../work/vim74/src/memline.c ./src/memline.c --- ../../work/vim74/src/memline.c 2013-05-06 05:01:02.000000000 +0300 +++ ./src/memline.c 2014-02-22 19:30:45.000000000 +0300 @@ -841,6 +841,9 @@ for (buf = firstbuf; buf != NULL; buf = buf->b_next) ml_close(buf, del_file && ((buf->b_flags & BF_PRESERVED) == 0 || vim_strchr(p_cpo, CPO_PRESERVE) == NULL)); +#ifdef FEAT_SPELL + spell_delete_wordlist(); /* delete the internal wordlist */ +#endif #ifdef TEMPDIRNAMES vim_deltempdir(); /* delete created temp directory */ #endif @@ -4014,6 +4017,13 @@ else retval = concat_fnames(dname, tail, TRUE); +#ifdef WIN3264 + if (retval != NULL) + for (t = gettail(retval); *t != NUL; mb_ptr_adv(t)) + if (*t == ':') + *t = '%'; +#endif + return retval; } @@ -4137,12 +4147,29 @@ #ifndef SHORT_FNAME int r; #endif + char_u *buf_fname = buf->b_fname; #if !defined(SHORT_FNAME) \ && ((!defined(UNIX) && !defined(OS2)) || defined(ARCHIE)) # define CREATE_DUMMY_FILE FILE *dummyfd = NULL; +# ifdef WIN3264 + if (buf_fname != NULL && !mch_isFullName(buf_fname) + && vim_strchr(gettail(buf_fname), ':')) + { + char_u *t; + + buf_fname = vim_strsave(buf_fname); + if (buf_fname == NULL) + buf_fname = buf->b_fname; + else + for (t = gettail(buf_fname); *t != NUL; mb_ptr_adv(t)) + if (*t == ':') + *t = '%'; + } +# endif + /* * If we start editing a new file, e.g. "test.doc", which resides on an * MSDOS compatible filesystem, it is possible that the file @@ -4150,9 +4177,9 @@ * this problem we temporarily create "test.doc". Don't do this when the * check below for a 8.3 file name is used. */ - if (!(buf->b_p_sn || buf->b_shortname) && buf->b_fname != NULL - && mch_getperm(buf->b_fname) < 0) - dummyfd = mch_fopen((char *)buf->b_fname, "w"); + if (!(buf->b_p_sn || buf->b_shortname) && buf_fname != NULL + && mch_getperm(buf_fname) < 0) + dummyfd = mch_fopen((char *)buf_fname, "w"); #endif /* @@ -4171,7 +4198,7 @@ if (dir_name == NULL) /* out of memory */ fname = NULL; else - fname = makeswapname(buf->b_fname, buf->b_ffname, buf, dir_name); + fname = makeswapname(buf_fname, buf->b_ffname, buf, dir_name); for (;;) { @@ -4204,7 +4231,7 @@ * It either contains two dots, is longer than 8 chars, or starts * with a dot. */ - tail = gettail(buf->b_fname); + tail = gettail(buf_fname); if ( vim_strchr(tail, '.') != NULL || STRLEN(tail) > (size_t)8 || *gettail(fname) == '.') @@ -4273,7 +4300,7 @@ { buf->b_shortname = TRUE; vim_free(fname); - fname = makeswapname(buf->b_fname, buf->b_ffname, + fname = makeswapname(buf_fname, buf->b_ffname, buf, dir_name); continue; /* try again with b_shortname set */ } @@ -4344,7 +4371,7 @@ { buf->b_shortname = TRUE; vim_free(fname); - fname = makeswapname(buf->b_fname, buf->b_ffname, + fname = makeswapname(buf_fname, buf->b_ffname, buf, dir_name); continue; /* try again with '.' replaced with '_' */ } @@ -4356,7 +4383,7 @@ * viewing a help file or when the path of the file is different * (happens when all .swp files are in one directory). */ - if (!recoverymode && buf->b_fname != NULL + if (!recoverymode && buf_fname != NULL && !buf->b_help && !(buf->b_flags & BF_DUMMY)) { int fd; @@ -4433,7 +4460,7 @@ { fclose(dummyfd); dummyfd = NULL; - mch_remove(buf->b_fname); + mch_remove(buf_fname); did_use_dummy = TRUE; } #endif @@ -4448,7 +4475,7 @@ * user anyway. */ if (swap_exists_action != SEA_NONE - && has_autocmd(EVENT_SWAPEXISTS, buf->b_fname, buf)) + && has_autocmd(EVENT_SWAPEXISTS, buf_fname, buf)) choice = do_swapexists(buf, fname); if (choice == 0) @@ -4549,7 +4576,7 @@ #ifdef CREATE_DUMMY_FILE /* Going to try another name, need the dummy file again. */ if (did_use_dummy) - dummyfd = mch_fopen((char *)buf->b_fname, "w"); + dummyfd = mch_fopen((char *)buf_fname, "w"); #endif } } @@ -4581,9 +4608,13 @@ if (dummyfd != NULL) /* file has been created temporarily */ { fclose(dummyfd); - mch_remove(buf->b_fname); + mch_remove(buf_fname); } #endif +#ifdef WIN3264 + if (buf_fname != buf->b_fname) + vim_free(buf_fname); +#endif return fname; } @@ -4883,7 +4914,7 @@ * block for the salt. */ vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset); bf_key_init(key, salt, (int)STRLEN(salt)); - bf_ofb_init(seed, MF_SEED_LEN); + bf_cfb_init(seed, MF_SEED_LEN); } } diff -ubBwrN ../../work/vim74/src/message.c ./src/message.c --- ../../work/vim74/src/message.c 2013-08-09 21:30:45.000000000 +0300 +++ ./src/message.c 2014-02-22 19:30:41.000000000 +0300 @@ -887,6 +887,8 @@ int oldState; int tmpState; int had_got_int; + int save_Recording; + FILE *save_scriptout; if (redraw == TRUE) must_redraw = CLEAR; @@ -957,11 +959,21 @@ * typeahead buffer. */ ++no_mapping; ++allow_keys; + + /* Temporarily disable Recording. If Recording is active, the + * character will be recorded later, since it will be added to the + * typebuf after the loop */ + save_Recording = Recording; + save_scriptout = scriptout; + Recording = FALSE; + scriptout = NULL; c = safe_vgetc(); if (had_got_int && !global_busy) got_int = FALSE; --no_mapping; --allow_keys; + Recording = save_Recording; + scriptout = save_scriptout; #ifdef FEAT_CLIPBOARD /* Strange way to allow copying (yanking) a modeless selection at diff -ubBwrN ../../work/vim74/src/misc1.c ./src/misc1.c --- ../../work/vim74/src/misc1.c 2013-08-03 18:29:33.000000000 +0300 +++ ./src/misc1.c 2014-02-22 19:30:42.000000000 +0300 @@ -303,10 +303,18 @@ ml_replace(curwin->w_cursor.lnum, newline, FALSE); if (flags & SIN_CHANGED) changed_bytes(curwin->w_cursor.lnum, 0); - /* Correct saved cursor position if it's after the indent. */ - if (saved_cursor.lnum == curwin->w_cursor.lnum - && saved_cursor.col >= (colnr_T)(p - oldline)) + /* Correct saved cursor position if it is in this line. */ + if (saved_cursor.lnum == curwin->w_cursor.lnum) + { + if (saved_cursor.col >= (colnr_T)(p - oldline)) + /* cursor was after the indent, adjust for the number of + * bytes added/removed */ saved_cursor.col += ind_len - (colnr_T)(p - oldline); + else if (saved_cursor.col >= (colnr_T)(s - newline)) + /* cursor was in the indent, and is now after it, put it back + * at the start of the indent (replacing spaces with TAB) */ + saved_cursor.col = (colnr_T)(s - newline); + } retval = TRUE; } else @@ -1397,7 +1405,7 @@ #ifdef FEAT_SMARTINDENT if (did_si) { - int sw = (int)get_sw_value(); + int sw = (int)get_sw_value(curbuf); if (p_sr) newindent -= newindent % sw; @@ -1581,9 +1589,9 @@ #if defined(FEAT_COMMENTS) || defined(PROTO) /* - * get_leader_len() returns the length of the prefix of the given string - * which introduces a comment. If this string is not a comment then 0 is - * returned. + * get_leader_len() returns the length in bytes of the prefix of the given + * string which introduces a comment. If this string is not a comment then + * 0 is returned. * When "flags" is not NULL, it is set to point to the flags of the recognized * comment leader. * "backward" must be true for the "O" command. @@ -4800,9 +4808,9 @@ if (fname == NULL) return (char_u *)""; - for (p1 = p2 = fname; *p2; ) /* find last part of path */ + for (p1 = p2 = get_past_head(fname); *p2; ) /* find last part of path */ { - if (vim_ispathsep(*p2)) + if (vim_ispathsep_nocolon(*p2)) p1 = p2 + 1; mb_ptr_adv(p2); } @@ -4921,7 +4929,8 @@ } /* - * return TRUE if 'c' is a path separator. + * Return TRUE if 'c' is a path separator. + * Note that for MS-Windows this includes the colon. */ int vim_ispathsep(c) @@ -4944,6 +4953,20 @@ #endif } +/* + * Like vim_ispathsep(c), but exclude the colon for MS-Windows. + */ + int +vim_ispathsep_nocolon(c) + int c; +{ + return vim_ispathsep(c) +#ifdef BACKSLASH_IN_FILENAME + && c != ':' +#endif + ; +} + #if defined(FEAT_SEARCHPATH) || defined(PROTO) /* * return TRUE if 'c' is a path list separator. @@ -5168,11 +5191,18 @@ #if defined(FEAT_CINDENT) || defined(FEAT_SYN_HL) static char_u *skip_string __ARGS((char_u *p)); +static pos_T *ind_find_start_comment __ARGS((void)); /* * Find the start of a comment, not knowing if we are in a comment right now. * Search starts at w_cursor.lnum and goes backwards. */ + static pos_T * +ind_find_start_comment() /* XXX */ +{ + return find_start_comment(curbuf->b_ind_maxcomment); +} + pos_T * find_start_comment(ind_maxcomment) /* XXX */ int ind_maxcomment; @@ -5290,7 +5320,7 @@ static int cin_isdefault __ARGS((char_u *)); static char_u *after_label __ARGS((char_u *l)); static int get_indent_nolabel __ARGS((linenr_T lnum)); -static int skip_label __ARGS((linenr_T, char_u **pp, int ind_maxcomment)); +static int skip_label __ARGS((linenr_T, char_u **pp)); static int cin_first_id_amount __ARGS((void)); static int cin_get_equal_amount __ARGS((linenr_T lnum)); static int cin_ispreproc __ARGS((char_u *)); @@ -5299,28 +5329,26 @@ static int cin_islinecomment __ARGS((char_u *)); static int cin_isterminated __ARGS((char_u *, int, int)); static int cin_isinit __ARGS((void)); -static int cin_isfuncdecl __ARGS((char_u **, linenr_T, linenr_T, int, int)); +static int cin_isfuncdecl __ARGS((char_u **, linenr_T, linenr_T)); static int cin_isif __ARGS((char_u *)); static int cin_iselse __ARGS((char_u *)); static int cin_isdo __ARGS((char_u *)); -static int cin_iswhileofdo __ARGS((char_u *, linenr_T, int)); +static int cin_iswhileofdo __ARGS((char_u *, linenr_T)); static int cin_is_if_for_while_before_offset __ARGS((char_u *line, int *poffset)); -static int cin_iswhileofdo_end __ARGS((int terminated, int ind_maxparen, int ind_maxcomment)); +static int cin_iswhileofdo_end __ARGS((int terminated)); static int cin_isbreak __ARGS((char_u *)); static int cin_is_cpp_baseclass __ARGS((colnr_T *col)); -static int get_baseclass_amount __ARGS((int col, int ind_maxparen, int ind_maxcomment, int ind_cpp_baseclass)); +static int get_baseclass_amount __ARGS((int col)); static int cin_ends_in __ARGS((char_u *, char_u *, char_u *)); static int cin_starts_with __ARGS((char_u *s, char *word)); static int cin_skip2pos __ARGS((pos_T *trypos)); -static pos_T *find_start_brace __ARGS((int)); -static pos_T *find_match_paren __ARGS((int, int)); -static int corr_ind_maxparen __ARGS((int ind_maxparen, pos_T *startpos)); +static pos_T *find_start_brace __ARGS((void)); +static pos_T *find_match_paren __ARGS((int)); +static int corr_ind_maxparen __ARGS((pos_T *startpos)); static int find_last_paren __ARGS((char_u *l, int start, int end)); -static int find_match __ARGS((int lookfor, linenr_T ourscope, int ind_maxparen, int ind_maxcomment)); +static int find_match __ARGS((int lookfor, linenr_T ourscope)); static int cin_is_cpp_namespace __ARGS((char_u *)); -static int ind_hash_comment = 0; /* # starts a comment */ - /* * Skip over white space and C comments within the line. * Also skip over Perl/shell comments if desired. @@ -5337,7 +5365,7 @@ /* Perl/shell # comment comment continues until eol. Require a space * before # to avoid recognizing $#array. */ - if (ind_hash_comment != 0 && s != prev_s && *s == '#') + if (curbuf->b_ind_hash_comment != 0 && s != prev_s && *s == '#') { s += STRLEN(s); break; @@ -5423,8 +5451,7 @@ * Note: curwin->w_cursor must be where we are looking for the label. */ int -cin_islabel(ind_maxcomment) /* XXX */ - int ind_maxcomment; +cin_islabel() /* XXX */ { char_u *s; @@ -5458,7 +5485,7 @@ * If we're in a comment now, skip to the start of the comment. */ curwin->w_cursor.col = 0; - if ((trypos = find_start_comment(ind_maxcomment)) != NULL) /* XXX */ + if ((trypos = ind_find_start_comment()) != NULL) /* XXX */ curwin->w_cursor = *trypos; line = ml_get_curline(); @@ -5704,10 +5731,9 @@ * ^ */ static int -skip_label(lnum, pp, ind_maxcomment) +skip_label(lnum, pp) linenr_T lnum; char_u **pp; - int ind_maxcomment; { char_u *l; int amount; @@ -5717,8 +5743,7 @@ curwin->w_cursor.lnum = lnum; l = ml_get_curline(); /* XXX */ - if (cin_iscase(l, FALSE) || cin_isscopedecl(l) - || cin_islabel(ind_maxcomment)) + if (cin_iscase(l, FALSE) || cin_isscopedecl(l) || cin_islabel()) { amount = get_indent_nolabel(lnum); l = after_label(ml_get_curline()); @@ -5962,12 +5987,10 @@ * "min_lnum" is the line before which we will not be looking. */ static int -cin_isfuncdecl(sp, first_lnum, min_lnum, ind_maxparen, ind_maxcomment) +cin_isfuncdecl(sp, first_lnum, min_lnum) char_u **sp; linenr_T first_lnum; linenr_T min_lnum; - int ind_maxparen; - int ind_maxcomment; { char_u *s; linenr_T lnum = first_lnum; @@ -5981,7 +6004,7 @@ s = *sp; if (find_last_paren(s, '(', ')') - && (trypos = find_match_paren(ind_maxparen, ind_maxcomment)) != NULL) + && (trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL) { lnum = trypos->lnum; if (lnum < min_lnum) @@ -6089,10 +6112,9 @@ * ')' and ';'. The condition may be spread over several lines. */ static int -cin_iswhileofdo(p, lnum, ind_maxparen) /* XXX */ +cin_iswhileofdo(p, lnum) /* XXX */ char_u *p; linenr_T lnum; - int ind_maxparen; { pos_T cursor_save; pos_T *trypos; @@ -6112,7 +6134,8 @@ ++p; ++curwin->w_cursor.col; } - if ((trypos = findmatchlimit(NULL, 0, 0, ind_maxparen)) != NULL + if ((trypos = findmatchlimit(NULL, 0, 0, + curbuf->b_ind_maxparen)) != NULL && *cin_skipcomment(ml_get_pos(trypos) + 1) == ';') retval = TRUE; curwin->w_cursor = cursor_save; @@ -6175,10 +6198,8 @@ * Adjust the cursor to the line with "while". */ static int -cin_iswhileofdo_end(terminated, ind_maxparen, ind_maxcomment) +cin_iswhileofdo_end(terminated) int terminated; - int ind_maxparen; - int ind_maxcomment; { char_u *line; char_u *p; @@ -6202,7 +6223,7 @@ * before the matching '('. XXX */ i = (int)(p - line); curwin->w_cursor.col = i; - trypos = find_match_paren(ind_maxparen, ind_maxcomment); + trypos = find_match_paren(curbuf->b_ind_maxparen); if (trypos != NULL) { s = cin_skipcomment(ml_get(trypos->lnum)); @@ -6394,11 +6415,8 @@ } static int -get_baseclass_amount(col, ind_maxparen, ind_maxcomment, ind_cpp_baseclass) +get_baseclass_amount(col) int col; - int ind_maxparen; - int ind_maxcomment; - int ind_cpp_baseclass; { int amount; colnr_T vcol; @@ -6408,11 +6426,10 @@ { amount = get_indent(); if (find_last_paren(ml_get_curline(), '(', ')') - && (trypos = find_match_paren(ind_maxparen, - ind_maxcomment)) != NULL) + && (trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL) amount = get_indent_lnum(trypos->lnum); /* XXX */ if (!cin_ends_in(ml_get_curline(), (char_u *)",", NULL)) - amount += ind_cpp_baseclass; + amount += curbuf->b_ind_cpp_baseclass; } else { @@ -6420,8 +6437,8 @@ getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL); amount = (int)vcol; } - if (amount < ind_cpp_baseclass) - amount = ind_cpp_baseclass; + if (amount < curbuf->b_ind_cpp_baseclass) + amount = curbuf->b_ind_cpp_baseclass; return amount; } @@ -6505,8 +6522,7 @@ /* } */ static pos_T * -find_start_brace(ind_maxcomment) /* XXX */ - int ind_maxcomment; +find_start_brace() /* XXX */ { pos_T cursor_save; pos_T *trypos; @@ -6522,7 +6538,7 @@ pos = NULL; /* ignore the { if it's in a // or / * * / comment */ if ((colnr_T)cin_skip2pos(trypos) == trypos->col - && (pos = find_start_comment(ind_maxcomment)) == NULL) /* XXX */ + && (pos = ind_find_start_comment()) == NULL) /* XXX */ break; if (pos != NULL) curwin->w_cursor.lnum = pos->lnum; @@ -6536,9 +6552,8 @@ * Return NULL if no match found. */ static pos_T * -find_match_paren(ind_maxparen, ind_maxcomment) /* XXX */ +find_match_paren(ind_maxparen) /* XXX */ int ind_maxparen; - int ind_maxcomment; { pos_T cursor_save; pos_T *trypos; @@ -6555,7 +6570,7 @@ pos_copy = *trypos; /* copy trypos, findmatch will change it */ trypos = &pos_copy; curwin->w_cursor = *trypos; - if (find_start_comment(ind_maxcomment) != NULL) /* XXX */ + if (ind_find_start_comment() != NULL) /* XXX */ trypos = NULL; } } @@ -6570,15 +6585,14 @@ * looking a few lines further. */ static int -corr_ind_maxparen(ind_maxparen, startpos) - int ind_maxparen; +corr_ind_maxparen(startpos) pos_T *startpos; { long n = (long)startpos->lnum - (long)curwin->w_cursor.lnum; - if (n > 0 && n < ind_maxparen / 2) - return ind_maxparen - (int)n; - return ind_maxparen; + if (n > 0 && n < curbuf->b_ind_maxparen / 2) + return curbuf->b_ind_maxparen - (int)n; + return curbuf->b_ind_maxparen; } /* @@ -6616,201 +6630,229 @@ return retval; } - int -get_c_indent() -{ - int sw = (int)get_sw_value(); - /* - * spaces from a block's opening brace the prevailing indent for that - * block should be + * Parse 'cinoptions' and set the values in "curbuf". + * Must be called when 'cinoptions', 'shiftwidth' and/or 'tabstop' changes. */ - - int ind_level = sw; + void +parse_cino(buf) + buf_T *buf; +{ + char_u *p; + char_u *l; + char_u *digits; + int n; + int divider; + int fraction = 0; + int sw = (int)get_sw_value(buf); /* - * spaces from the edge of the line an open brace that's at the end of a - * line is imagined to be. + * Set the default values. */ - int ind_open_imag = 0; + /* Spaces from a block's opening brace the prevailing indent for that + * block should be. */ + buf->b_ind_level = sw; - /* - * spaces from the prevailing indent for a line that is not preceded by - * an opening brace. - */ - int ind_no_brace = 0; + /* Spaces from the edge of the line an open brace that's at the end of a + * line is imagined to be. */ + buf->b_ind_open_imag = 0; - /* - * column where the first { of a function should be located } - */ - int ind_first_open = 0; + /* Spaces from the prevailing indent for a line that is not preceded by + * an opening brace. */ + buf->b_ind_no_brace = 0; - /* - * spaces from the prevailing indent a leftmost open brace should be - * located - */ - int ind_open_extra = 0; + /* Column where the first { of a function should be located }. */ + buf->b_ind_first_open = 0; - /* - * spaces from the matching open brace (real location for one at the left + /* Spaces from the prevailing indent a leftmost open brace should be + * located. */ + buf->b_ind_open_extra = 0; + + /* Spaces from the matching open brace (real location for one at the left * edge; imaginary location from one that ends a line) the matching close - * brace should be located - */ - int ind_close_extra = 0; + * brace should be located. */ + buf->b_ind_close_extra = 0; - /* - * spaces from the edge of the line an open brace sitting in the leftmost - * column is imagined to be - */ - int ind_open_left_imag = 0; + /* Spaces from the edge of the line an open brace sitting in the leftmost + * column is imagined to be. */ + buf->b_ind_open_left_imag = 0; - /* - * Spaces jump labels should be shifted to the left if N is non-negative, - * otherwise the jump label will be put to column 1. - */ - int ind_jump_label = -1; + /* Spaces jump labels should be shifted to the left if N is non-negative, + * otherwise the jump label will be put to column 1. */ + buf->b_ind_jump_label = -1; - /* - * spaces from the switch() indent a "case xx" label should be located - */ - int ind_case = sw; + /* Spaces from the switch() indent a "case xx" label should be located. */ + buf->b_ind_case = sw; - /* - * spaces from the "case xx:" code after a switch() should be located - */ - int ind_case_code = sw; + /* Spaces from the "case xx:" code after a switch() should be located. */ + buf->b_ind_case_code = sw; - /* - * lineup break at end of case in switch() with case label - */ - int ind_case_break = 0; + /* Lineup break at end of case in switch() with case label. */ + buf->b_ind_case_break = 0; - /* - * spaces from the class declaration indent a scope declaration label - * should be located - */ - int ind_scopedecl = sw; + /* Spaces from the class declaration indent a scope declaration label + * should be located. */ + buf->b_ind_scopedecl = sw; - /* - * spaces from the scope declaration label code should be located - */ - int ind_scopedecl_code = sw; + /* Spaces from the scope declaration label code should be located. */ + buf->b_ind_scopedecl_code = sw; - /* - * amount K&R-style parameters should be indented - */ - int ind_param = sw; + /* Amount K&R-style parameters should be indented. */ + buf->b_ind_param = sw; - /* - * amount a function type spec should be indented - */ - int ind_func_type = sw; + /* Amount a function type spec should be indented. */ + buf->b_ind_func_type = sw; - /* - * amount a cpp base class declaration or constructor initialization - * should be indented - */ - int ind_cpp_baseclass = sw; + /* Amount a cpp base class declaration or constructor initialization + * should be indented. */ + buf->b_ind_cpp_baseclass = sw; - /* - * additional spaces beyond the prevailing indent a continuation line - * should be located - */ - int ind_continuation = sw; + /* additional spaces beyond the prevailing indent a continuation line + * should be located. */ + buf->b_ind_continuation = sw; - /* - * spaces from the indent of the line with an unclosed parentheses - */ - int ind_unclosed = sw * 2; + /* Spaces from the indent of the line with an unclosed parentheses. */ + buf->b_ind_unclosed = sw * 2; - /* - * spaces from the indent of the line with an unclosed parentheses, which - * itself is also unclosed - */ - int ind_unclosed2 = sw; + /* Spaces from the indent of the line with an unclosed parentheses, which + * itself is also unclosed. */ + buf->b_ind_unclosed2 = sw; - /* - * suppress ignoring spaces from the indent of a line starting with an - * unclosed parentheses. - */ - int ind_unclosed_noignore = 0; + /* Suppress ignoring spaces from the indent of a line starting with an + * unclosed parentheses. */ + buf->b_ind_unclosed_noignore = 0; - /* - * If the opening paren is the last nonwhite character on the line, and - * ind_unclosed_wrapped is nonzero, use this indent relative to the outer - * context (for very long lines). - */ - int ind_unclosed_wrapped = 0; + /* If the opening paren is the last nonwhite character on the line, and + * b_ind_unclosed_wrapped is nonzero, use this indent relative to the outer + * context (for very long lines). */ + buf->b_ind_unclosed_wrapped = 0; - /* - * suppress ignoring white space when lining up with the character after - * an unclosed parentheses. - */ - int ind_unclosed_whiteok = 0; + /* Suppress ignoring white space when lining up with the character after + * an unclosed parentheses. */ + buf->b_ind_unclosed_whiteok = 0; - /* - * indent a closing parentheses under the line start of the matching - * opening parentheses. - */ - int ind_matching_paren = 0; + /* Indent a closing parentheses under the line start of the matching + * opening parentheses. */ + buf->b_ind_matching_paren = 0; - /* - * indent a closing parentheses under the previous line. - */ - int ind_paren_prev = 0; + /* Indent a closing parentheses under the previous line. */ + buf->b_ind_paren_prev = 0; - /* - * Extra indent for comments. - */ - int ind_comment = 0; + /* Extra indent for comments. */ + buf->b_ind_comment = 0; - /* - * spaces from the comment opener when there is nothing after it. - */ - int ind_in_comment = 3; + /* Spaces from the comment opener when there is nothing after it. */ + buf->b_ind_in_comment = 3; - /* - * boolean: if non-zero, use ind_in_comment even if there is something - * after the comment opener. - */ - int ind_in_comment2 = 0; + /* Boolean: if non-zero, use b_ind_in_comment even if there is something + * after the comment opener. */ + buf->b_ind_in_comment2 = 0; - /* - * max lines to search for an open paren - */ - int ind_maxparen = 20; + /* Max lines to search for an open paren. */ + buf->b_ind_maxparen = 20; - /* - * max lines to search for an open comment - */ - int ind_maxcomment = 70; + /* Max lines to search for an open comment. */ + buf->b_ind_maxcomment = 70; - /* - * handle braces for java code - */ - int ind_java = 0; + /* Handle braces for java code. */ + buf->b_ind_java = 0; - /* - * not to confuse JS object properties with labels - */ - int ind_js = 0; + /* Not to confuse JS object properties with labels. */ + buf->b_ind_js = 0; - /* - * handle blocked cases correctly - */ - int ind_keep_case_label = 0; + /* Handle blocked cases correctly. */ + buf->b_ind_keep_case_label = 0; - /* - * handle C++ namespace - */ - int ind_cpp_namespace = 0; + /* Handle C++ namespace. */ + buf->b_ind_cpp_namespace = 0; - /* - * handle continuation lines containing conditions of if(), for() and - * while() - */ - int ind_if_for_while = 0; + /* Handle continuation lines containing conditions of if(), for() and + * while(). */ + buf->b_ind_if_for_while = 0; + for (p = buf->b_p_cino; *p; ) + { + l = p++; + if (*p == '-') + ++p; + digits = p; /* remember where the digits start */ + n = getdigits(&p); + divider = 0; + if (*p == '.') /* ".5s" means a fraction */ + { + fraction = atol((char *)++p); + while (VIM_ISDIGIT(*p)) + { + ++p; + if (divider) + divider *= 10; + else + divider = 10; + } + } + if (*p == 's') /* "2s" means two times 'shiftwidth' */ + { + if (p == digits) + n = sw; /* just "s" is one 'shiftwidth' */ + else + { + n *= sw; + if (divider) + n += (sw * fraction + divider / 2) / divider; + } + ++p; + } + if (l[1] == '-') + n = -n; + + /* When adding an entry here, also update the default 'cinoptions' in + * doc/indent.txt, and add explanation for it! */ + switch (*l) + { + case '>': buf->b_ind_level = n; break; + case 'e': buf->b_ind_open_imag = n; break; + case 'n': buf->b_ind_no_brace = n; break; + case 'f': buf->b_ind_first_open = n; break; + case '{': buf->b_ind_open_extra = n; break; + case '}': buf->b_ind_close_extra = n; break; + case '^': buf->b_ind_open_left_imag = n; break; + case 'L': buf->b_ind_jump_label = n; break; + case ':': buf->b_ind_case = n; break; + case '=': buf->b_ind_case_code = n; break; + case 'b': buf->b_ind_case_break = n; break; + case 'p': buf->b_ind_param = n; break; + case 't': buf->b_ind_func_type = n; break; + case '/': buf->b_ind_comment = n; break; + case 'c': buf->b_ind_in_comment = n; break; + case 'C': buf->b_ind_in_comment2 = n; break; + case 'i': buf->b_ind_cpp_baseclass = n; break; + case '+': buf->b_ind_continuation = n; break; + case '(': buf->b_ind_unclosed = n; break; + case 'u': buf->b_ind_unclosed2 = n; break; + case 'U': buf->b_ind_unclosed_noignore = n; break; + case 'W': buf->b_ind_unclosed_wrapped = n; break; + case 'w': buf->b_ind_unclosed_whiteok = n; break; + case 'm': buf->b_ind_matching_paren = n; break; + case 'M': buf->b_ind_paren_prev = n; break; + case ')': buf->b_ind_maxparen = n; break; + case '*': buf->b_ind_maxcomment = n; break; + case 'g': buf->b_ind_scopedecl = n; break; + case 'h': buf->b_ind_scopedecl_code = n; break; + case 'j': buf->b_ind_java = n; break; + case 'J': buf->b_ind_js = n; break; + case 'l': buf->b_ind_keep_case_label = n; break; + case '#': buf->b_ind_hash_comment = n; break; + case 'N': buf->b_ind_cpp_namespace = n; break; + case 'k': buf->b_ind_if_for_while = n; break; + } + if (*p == ',') + ++p; + } +} + + int +get_c_indent() +{ pos_T cur_curpos; int amount; int scope_amount; @@ -6845,10 +6887,6 @@ int whilelevel; linenr_T lnum; - char_u *options; - char_u *digits; - int fraction = 0; /* init for GCC */ - int divider; int n; int iscase; int lookfor_break; @@ -6857,83 +6895,8 @@ int original_line_islabel; int added_to_amount = 0; - for (options = curbuf->b_p_cino; *options; ) - { - l = options++; - if (*options == '-') - ++options; - digits = options; /* remember where the digits start */ - n = getdigits(&options); - divider = 0; - if (*options == '.') /* ".5s" means a fraction */ - { - fraction = atol((char *)++options); - while (VIM_ISDIGIT(*options)) - { - ++options; - if (divider) - divider *= 10; - else - divider = 10; - } - } - if (*options == 's') /* "2s" means two times 'shiftwidth' */ - { - if (options == digits) - n = sw; /* just "s" is one 'shiftwidth' */ - else - { - n *= sw; - if (divider) - n += (sw * fraction + divider / 2) / divider; - } - ++options; - } - if (l[1] == '-') - n = -n; - /* When adding an entry here, also update the default 'cinoptions' in - * doc/indent.txt, and add explanation for it! */ - switch (*l) - { - case '>': ind_level = n; break; - case 'e': ind_open_imag = n; break; - case 'n': ind_no_brace = n; break; - case 'f': ind_first_open = n; break; - case '{': ind_open_extra = n; break; - case '}': ind_close_extra = n; break; - case '^': ind_open_left_imag = n; break; - case 'L': ind_jump_label = n; break; - case ':': ind_case = n; break; - case '=': ind_case_code = n; break; - case 'b': ind_case_break = n; break; - case 'p': ind_param = n; break; - case 't': ind_func_type = n; break; - case '/': ind_comment = n; break; - case 'c': ind_in_comment = n; break; - case 'C': ind_in_comment2 = n; break; - case 'i': ind_cpp_baseclass = n; break; - case '+': ind_continuation = n; break; - case '(': ind_unclosed = n; break; - case 'u': ind_unclosed2 = n; break; - case 'U': ind_unclosed_noignore = n; break; - case 'W': ind_unclosed_wrapped = n; break; - case 'w': ind_unclosed_whiteok = n; break; - case 'm': ind_matching_paren = n; break; - case 'M': ind_paren_prev = n; break; - case ')': ind_maxparen = n; break; - case '*': ind_maxcomment = n; break; - case 'g': ind_scopedecl = n; break; - case 'h': ind_scopedecl_code = n; break; - case 'j': ind_java = n; break; - case 'J': ind_js = n; break; - case 'l': ind_keep_case_label = n; break; - case '#': ind_hash_comment = n; break; - case 'N': ind_cpp_namespace = n; break; - case 'k': ind_if_for_while = n; break; - } - if (*options == ',') - ++options; - } + /* make a copy, value is changed below */ + int ind_continuation = curbuf->b_ind_continuation; /* remember where the cursor was when we started */ cur_curpos = curwin->w_cursor; @@ -6967,22 +6930,21 @@ curwin->w_cursor.col = 0; - original_line_islabel = cin_islabel(ind_maxcomment); /* XXX */ + original_line_islabel = cin_islabel(); /* XXX */ /* * #defines and so on always go at the left when included in 'cinkeys'. */ if (*theline == '#' && (*linecopy == '#' || in_cinkeys('#', ' ', TRUE))) - { - amount = 0; - } + amount = curbuf->b_ind_hash_comment; /* * Is it a non-case label? Then that goes at the left margin too unless: * - JS flag is set. * - 'L' item has a positive value. */ - else if (original_line_islabel && !ind_js && ind_jump_label < 0) + else if (original_line_islabel && !curbuf->b_ind_js + && curbuf->b_ind_jump_label < 0) { amount = 0; } @@ -7004,7 +6966,8 @@ * comment, try using the 'comments' option. */ else if (!cin_iscomment(theline) - && (trypos = find_start_comment(ind_maxcomment)) != NULL) /* XXX */ + && (trypos = ind_find_start_comment()) != NULL) + /* XXX */ { int lead_start_len = 2; int lead_middle_len = 1; @@ -7138,7 +7101,7 @@ } if (amount == -1) /* use the comment opener */ { - if (!ind_in_comment2) + if (!curbuf->b_ind_in_comment2) { start = ml_get(trypos->lnum); look = start + trypos->col + 2; /* skip / and * */ @@ -7147,8 +7110,8 @@ } getvcol(curwin, trypos, &col, NULL, NULL); amount = col; - if (ind_in_comment2 || *look == NUL) - amount += ind_in_comment; + if (curbuf->b_ind_in_comment2 || *look == NUL) + amount += curbuf->b_ind_in_comment; } } } @@ -7156,9 +7119,9 @@ /* * Are we inside parentheses or braces? */ /* XXX */ - else if (((trypos = find_match_paren(ind_maxparen, ind_maxcomment)) != NULL - && ind_java == 0) - || (tryposBrace = find_start_brace(ind_maxcomment)) != NULL + else if (((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL + && curbuf->b_ind_java == 0) + || (tryposBrace = find_start_brace()) != NULL || trypos != NULL) { if (trypos != NULL && tryposBrace != NULL) @@ -7179,7 +7142,7 @@ * If the matching paren is more than one line away, use the indent of * a previous non-empty line that matches the same paren. */ - if (theline[0] == ')' && ind_paren_prev) + if (theline[0] == ')' && curbuf->b_ind_paren_prev) { /* Line up with the start of the matching paren line. */ amount = get_indent_lnum(curwin->w_cursor.lnum - 1); /* XXX */ @@ -7198,7 +7161,7 @@ curwin->w_cursor.lnum = lnum; /* Skip a comment. XXX */ - if ((trypos = find_start_comment(ind_maxcomment)) != NULL) + if ((trypos = ind_find_start_comment()) != NULL) { lnum = trypos->lnum + 1; continue; @@ -7206,8 +7169,7 @@ /* XXX */ if ((trypos = find_match_paren( - corr_ind_maxparen(ind_maxparen, &cur_curpos), - ind_maxcomment)) != NULL + corr_ind_maxparen(&cur_curpos))) != NULL && trypos->lnum == our_paren_pos.lnum && trypos->col == our_paren_pos.col) { @@ -7235,7 +7197,7 @@ int ignore_paren_col = 0; int is_if_for_while = 0; - if (ind_if_for_while) + if (curbuf->b_ind_if_for_while) { /* Look for the outermost opening parenthesis on this line * and check whether it belongs to an "if", "for" or "while". */ @@ -7250,7 +7212,7 @@ curwin->w_cursor.lnum = outermost.lnum; curwin->w_cursor.col = outermost.col; - trypos = find_match_paren(ind_maxparen, ind_maxcomment); + trypos = find_match_paren(curbuf->b_ind_maxparen); } while (trypos && trypos->lnum == outermost.lnum); curwin->w_cursor = cursor_save; @@ -7261,7 +7223,7 @@ cin_is_if_for_while_before_offset(line, &outermost.col); } - amount = skip_label(our_paren_pos.lnum, &look, ind_maxcomment); + amount = skip_label(our_paren_pos.lnum, &look); look = skipwhite(look); if (*look == '(') { @@ -7275,7 +7237,8 @@ line = ml_get_curline(); look_col = (int)(look - line); curwin->w_cursor.col = look_col + 1; - if ((trypos = findmatchlimit(NULL, ')', 0, ind_maxparen)) + if ((trypos = findmatchlimit(NULL, ')', 0, + curbuf->b_ind_maxparen)) != NULL && trypos->lnum == our_paren_pos.lnum && trypos->col < our_paren_pos.col) @@ -7284,24 +7247,25 @@ curwin->w_cursor.lnum = save_lnum; look = ml_get(our_paren_pos.lnum) + look_col; } - if (theline[0] == ')' || (ind_unclosed == 0 && is_if_for_while == 0) - || (!ind_unclosed_noignore && *look == '(' + if (theline[0] == ')' || (curbuf->b_ind_unclosed == 0 + && is_if_for_while == 0) + || (!curbuf->b_ind_unclosed_noignore && *look == '(' && ignore_paren_col == 0)) { /* * If we're looking at a close paren, line up right there; * otherwise, line up with the next (non-white) character. - * When ind_unclosed_wrapped is set and the matching paren is + * When b_ind_unclosed_wrapped is set and the matching paren is * the last nonwhite character of the line, use either the * indent of the current line or the indentation of the next - * outer paren and add ind_unclosed_wrapped (for very long + * outer paren and add b_ind_unclosed_wrapped (for very long * lines). */ if (theline[0] != ')') { cur_amount = MAXCOL; l = ml_get(our_paren_pos.lnum); - if (ind_unclosed_wrapped + if (curbuf->b_ind_unclosed_wrapped && cin_ends_in(l, (char_u *)"(", NULL)) { /* look for opening unmatched paren, indent one level @@ -7323,9 +7287,9 @@ } our_paren_pos.col = 0; - amount += n * ind_unclosed_wrapped; + amount += n * curbuf->b_ind_unclosed_wrapped; } - else if (ind_unclosed_whiteok) + else if (curbuf->b_ind_unclosed_whiteok) our_paren_pos.col++; else { @@ -7351,12 +7315,12 @@ } } - if (theline[0] == ')' && ind_matching_paren) + if (theline[0] == ')' && curbuf->b_ind_matching_paren) { /* Line up with the start of the matching paren line. */ } - else if ((ind_unclosed == 0 && is_if_for_while == 0) - || (!ind_unclosed_noignore + else if ((curbuf->b_ind_unclosed == 0 && is_if_for_while == 0) + || (!curbuf->b_ind_unclosed_noignore && *look == '(' && ignore_paren_col == 0)) { if (cur_amount != MAXCOL) @@ -7364,39 +7328,39 @@ } else { - /* Add ind_unclosed2 for each '(' before our matching one, but - * ignore (void) before the line (ignore_paren_col). */ + /* Add b_ind_unclosed2 for each '(' before our matching one, + * but ignore (void) before the line (ignore_paren_col). */ col = our_paren_pos.col; while ((int)our_paren_pos.col > ignore_paren_col) { --our_paren_pos.col; switch (*ml_get_pos(&our_paren_pos)) { - case '(': amount += ind_unclosed2; + case '(': amount += curbuf->b_ind_unclosed2; col = our_paren_pos.col; break; - case ')': amount -= ind_unclosed2; + case ')': amount -= curbuf->b_ind_unclosed2; col = MAXCOL; break; } } - /* Use ind_unclosed once, when the first '(' is not inside + /* Use b_ind_unclosed once, when the first '(' is not inside * braces */ if (col == MAXCOL) - amount += ind_unclosed; + amount += curbuf->b_ind_unclosed; else { curwin->w_cursor.lnum = our_paren_pos.lnum; curwin->w_cursor.col = col; - if (find_match_paren(ind_maxparen, ind_maxcomment) != NULL) - amount += ind_unclosed2; + if (find_match_paren(curbuf->b_ind_maxparen) != NULL) + amount += curbuf->b_ind_unclosed2; else { if (is_if_for_while) - amount += ind_if_for_while; + amount += curbuf->b_ind_if_for_while; else - amount += ind_unclosed; + amount += curbuf->b_ind_unclosed; } } /* @@ -7414,7 +7378,7 @@ /* add extra indent for a comment */ if (cin_iscomment(theline)) - amount += ind_comment; + amount += curbuf->b_ind_comment; } /* @@ -7457,8 +7421,8 @@ */ lnum = ourscope; if (find_last_paren(start, '(', ')') - && (trypos = find_match_paren(ind_maxparen, - ind_maxcomment)) != NULL) + && (trypos = find_match_paren(curbuf->b_ind_maxparen)) + != NULL) lnum = trypos->lnum; /* @@ -7467,11 +7431,11 @@ * ldfd) { * } */ - if (ind_js || (ind_keep_case_label + if (curbuf->b_ind_js || (curbuf->b_ind_keep_case_label && cin_iscase(skipwhite(ml_get_curline()), FALSE))) amount = get_indent(); else - amount = skip_label(lnum, &l, ind_maxcomment); + amount = skip_label(lnum, &l); start_brace = BRACE_AT_END; } @@ -7487,7 +7451,7 @@ * they may want closing braces to line up with something * other than the open brace. indulge them, if so. */ - amount += ind_close_extra; + amount += curbuf->b_ind_close_extra; } else { @@ -7500,14 +7464,12 @@ lookfor = LOOKFOR_INITIAL; if (cin_iselse(theline)) lookfor = LOOKFOR_IF; - else if (cin_iswhileofdo(theline, cur_curpos.lnum, ind_maxparen)) - /* XXX */ + else if (cin_iswhileofdo(theline, cur_curpos.lnum)) /* XXX */ lookfor = LOOKFOR_DO; if (lookfor != LOOKFOR_INITIAL) { curwin->w_cursor.lnum = cur_curpos.lnum; - if (find_match(lookfor, ourscope, ind_maxparen, - ind_maxcomment) == OK) + if (find_match(lookfor, ourscope) == OK) { amount = get_indent(); /* XXX */ goto theend; @@ -7524,12 +7486,12 @@ /* * if the '{' is _really_ at the left margin, use the imaginary * location of a left-margin brace. Otherwise, correct the - * location for ind_open_extra. + * location for b_ind_open_extra. */ if (start_brace == BRACE_IN_COL0) /* '{' is in column 0 */ { - amount = ind_open_left_imag; + amount = curbuf->b_ind_open_left_imag; lookfor_cpp_namespace = TRUE; } else if (start_brace == BRACE_AT_START && @@ -7542,16 +7504,16 @@ { if (start_brace == BRACE_AT_END) /* '{' is at end of line */ { - amount += ind_open_imag; + amount += curbuf->b_ind_open_imag; l = skipwhite(ml_get_curline()); if (cin_is_cpp_namespace(l)) - amount += ind_cpp_namespace; + amount += curbuf->b_ind_cpp_namespace; } else { - /* Compensate for adding ind_open_extra later. */ - amount -= ind_open_extra; + /* Compensate for adding b_ind_open_extra later. */ + amount -= curbuf->b_ind_open_extra; if (amount < 0) amount = 0; } @@ -7562,20 +7524,22 @@ if (cin_iscase(theline, FALSE)) /* it's a switch() label */ { lookfor = LOOKFOR_CASE; /* find a previous switch() label */ - amount += ind_case; + amount += curbuf->b_ind_case; } else if (cin_isscopedecl(theline)) /* private:, ... */ { lookfor = LOOKFOR_SCOPEDECL; /* class decl is this block */ - amount += ind_scopedecl; + amount += curbuf->b_ind_scopedecl; } else { - if (ind_case_break && cin_isbreak(theline)) /* break; ... */ + if (curbuf->b_ind_case_break && cin_isbreak(theline)) + /* break; ... */ lookfor_break = TRUE; lookfor = LOOKFOR_INITIAL; - amount += ind_level; /* ind_level from start of block */ + /* b_ind_level from start of block */ + amount += curbuf->b_ind_level; } scope_amount = amount; whilelevel = 0; @@ -7613,14 +7577,14 @@ { if (curwin->w_cursor.lnum == 0 || curwin->w_cursor.lnum - < ourscope - ind_maxparen) + < ourscope - curbuf->b_ind_maxparen) { - /* nothing found (abuse ind_maxparen as limit) - * assume terminated line (i.e. a variable + /* nothing found (abuse curbuf->b_ind_maxparen as + * limit) assume terminated line (i.e. a variable * initialization) */ if (cont_amount > 0) amount = cont_amount; - else if (!ind_js) + else if (!curbuf->b_ind_js) amount += ind_continuation; break; } @@ -7631,7 +7595,7 @@ * If we're in a comment now, skip to the start of the * comment. */ - trypos = find_start_comment(ind_maxcomment); + trypos = ind_find_start_comment(); if (trypos != NULL) { curwin->w_cursor.lnum = trypos->lnum + 1; @@ -7656,8 +7620,7 @@ * (it's a variable declaration). */ if (start_brace != BRACE_IN_COL0 - || !cin_isfuncdecl(&l, curwin->w_cursor.lnum, - 0, ind_maxparen, ind_maxcomment)) + || !cin_isfuncdecl(&l, curwin->w_cursor.lnum, 0)) { /* if the line is terminated with another ',' * it is a continued variable initialization. @@ -7688,11 +7651,11 @@ */ /* XXX */ trypos = NULL; if (find_last_paren(l, '(', ')')) - trypos = find_match_paren(ind_maxparen, - ind_maxcomment); + trypos = find_match_paren( + curbuf->b_ind_maxparen); if (trypos == NULL && find_last_paren(l, '{', '}')) - trypos = find_start_brace(ind_maxcomment); + trypos = find_start_brace(); if (trypos != NULL) { @@ -7727,8 +7690,8 @@ amount = scope_amount; if (theline[0] == '{') { - amount += ind_open_extra; - added_to_amount = ind_open_extra; + amount += curbuf->b_ind_open_extra; + added_to_amount = curbuf->b_ind_open_extra; } } @@ -7750,7 +7713,7 @@ /* If we're in a comment now, skip to the start of * the comment. */ - trypos = find_start_comment(ind_maxcomment); + trypos = ind_find_start_comment(); if (trypos != NULL) { curwin->w_cursor.lnum = trypos->lnum + 1; @@ -7765,7 +7728,8 @@ /* Finally the actual check for "namespace". */ if (cin_is_cpp_namespace(l)) { - amount += ind_cpp_namespace - added_to_amount; + amount += curbuf->b_ind_cpp_namespace + - added_to_amount; break; } @@ -7779,7 +7743,7 @@ /* * If we're in a comment now, skip to the start of the comment. */ /* XXX */ - if ((trypos = find_start_comment(ind_maxcomment)) != NULL) + if ((trypos = ind_find_start_comment()) != NULL) { curwin->w_cursor.lnum = trypos->lnum + 1; curwin->w_cursor.col = 0; @@ -7833,8 +7797,8 @@ * Check that this case label is not for another * switch() */ /* XXX */ - if ((trypos = find_start_brace(ind_maxcomment)) == - NULL || trypos->lnum == ourscope) + if ((trypos = find_start_brace()) == NULL + || trypos->lnum == ourscope) { amount = get_indent(); /* XXX */ break; @@ -7877,9 +7841,10 @@ if (l != NULL && cin_is_cinword(l)) { if (theline[0] == '{') - amount += ind_open_extra; + amount += curbuf->b_ind_open_extra; else - amount += ind_level + ind_no_brace; + amount += curbuf->b_ind_level + + curbuf->b_ind_no_brace; } break; } @@ -7893,8 +7858,10 @@ * -> y = 1; */ scope_amount = get_indent() + (iscase /* XXX */ - ? ind_case_code : ind_scopedecl_code); - lookfor = ind_case_break ? LOOKFOR_NOBREAK : LOOKFOR_ANY; + ? curbuf->b_ind_case_code + : curbuf->b_ind_scopedecl_code); + lookfor = curbuf->b_ind_case_break + ? LOOKFOR_NOBREAK : LOOKFOR_ANY; continue; } @@ -7904,8 +7871,8 @@ */ if (lookfor == LOOKFOR_CASE || lookfor == LOOKFOR_SCOPEDECL) { - if (find_last_paren(l, '{', '}') && (trypos = - find_start_brace(ind_maxcomment)) != NULL) + if (find_last_paren(l, '{', '}') + && (trypos = find_start_brace()) != NULL) { curwin->w_cursor.lnum = trypos->lnum + 1; curwin->w_cursor.col = 0; @@ -7916,7 +7883,7 @@ /* * Ignore jump labels with nothing after them. */ - if (!ind_js && cin_islabel(ind_maxcomment)) + if (!curbuf->b_ind_js && cin_islabel()) { l = after_label(ml_get_curline()); if (l == NULL || cin_nocode(l)) @@ -7939,7 +7906,7 @@ * constructor initialization? */ /* XXX */ n = FALSE; - if (lookfor != LOOKFOR_TERM && ind_cpp_baseclass > 0) + if (lookfor != LOOKFOR_TERM && curbuf->b_ind_cpp_baseclass > 0) { n = cin_is_cpp_baseclass(&col); l = ml_get_curline(); @@ -7962,8 +7929,7 @@ } else /* XXX */ - amount = get_baseclass_amount(col, ind_maxparen, - ind_maxcomment, ind_cpp_baseclass); + amount = get_baseclass_amount(col); break; } else if (lookfor == LOOKFOR_CPP_BASECLASS) @@ -8005,9 +7971,7 @@ * matching it will take us back to the start of the line. */ (void)find_last_paren(l, '(', ')'); - trypos = find_match_paren( - corr_ind_maxparen(ind_maxparen, &cur_curpos), - ind_maxcomment); + trypos = find_match_paren(corr_ind_maxparen(&cur_curpos)); /* * If we are looking for ',', we also look for matching @@ -8015,7 +7979,7 @@ */ if (trypos == NULL && terminated == ',' && find_last_paren(l, '{', '}')) - trypos = find_start_brace(ind_maxcomment); + trypos = find_start_brace(); if (trypos != NULL) { @@ -8058,9 +8022,8 @@ * Get indent and pointer to text for current line, * ignoring any jump label. XXX */ - if (!ind_js) - cur_amount = skip_label(curwin->w_cursor.lnum, - &l, ind_maxcomment); + if (!curbuf->b_ind_js) + cur_amount = skip_label(curwin->w_cursor.lnum, &l); else cur_amount = get_indent(); /* @@ -8075,16 +8038,16 @@ { amount = cur_amount; /* - * Only add ind_open_extra when the current line + * Only add b_ind_open_extra when the current line * doesn't start with a '{', which must have a match * in the same line (scope is the same). Probably: * { 1, 2 }, * -> { 3, 4 } */ if (*skipwhite(l) != '{') - amount += ind_open_extra; + amount += curbuf->b_ind_open_extra; - if (ind_cpp_baseclass) + if (curbuf->b_ind_cpp_baseclass) { /* have to look back, whether it is a cpp base * class declaration or initialization */ @@ -8132,10 +8095,11 @@ */ amount = cur_amount; if (theline[0] == '{') - amount += ind_open_extra; + amount += curbuf->b_ind_open_extra; if (lookfor != LOOKFOR_TERM) { - amount += ind_level + ind_no_brace; + amount += curbuf->b_ind_level + + curbuf->b_ind_no_brace; break; } @@ -8169,10 +8133,9 @@ curwin->w_cursor.col = (colnr_T)(l - ml_get_curline()) + 1; - if ((trypos = find_start_brace(ind_maxcomment)) - == NULL - || find_match(LOOKFOR_IF, trypos->lnum, - ind_maxparen, ind_maxcomment) == FAIL) + if ((trypos = find_start_brace()) == NULL + || find_match(LOOKFOR_IF, trypos->lnum) + == FAIL) break; } } @@ -8209,7 +8172,7 @@ * enumerations/initializations. */ if (terminated == ',') { - if (ind_cpp_baseclass == 0) + if (curbuf->b_ind_cpp_baseclass == 0) break; lookfor = LOOKFOR_CPP_BASECLASS; @@ -8267,8 +8230,7 @@ * If so: Ignore until the matching "do". */ /* XXX */ - else if (cin_iswhileofdo_end(terminated, ind_maxparen, - ind_maxcomment)) + else if (cin_iswhileofdo_end(terminated)) { /* * Found an unterminated line after a while ();, line up @@ -8292,7 +8254,7 @@ lookfor = LOOKFOR_TERM; amount = get_indent(); /* XXX */ if (theline[0] == '{') - amount += ind_open_extra; + amount += curbuf->b_ind_open_extra; } ++whilelevel; } @@ -8385,8 +8347,8 @@ term_again: l = ml_get_curline(); if (find_last_paren(l, '(', ')') - && (trypos = find_match_paren(ind_maxparen, - ind_maxcomment)) != NULL) + && (trypos = find_match_paren( + curbuf->b_ind_maxparen)) != NULL) { /* * Check if we are on a case label now. This is @@ -8413,21 +8375,21 @@ * stat; * } */ - iscase = (ind_keep_case_label && cin_iscase(l, FALSE)); + iscase = (curbuf->b_ind_keep_case_label + && cin_iscase(l, FALSE)); /* * Get indent and pointer to text for current line, * ignoring any jump label. */ - amount = skip_label(curwin->w_cursor.lnum, - &l, ind_maxcomment); + amount = skip_label(curwin->w_cursor.lnum, &l); if (theline[0] == '{') - amount += ind_open_extra; - /* See remark above: "Only add ind_open_extra.." */ + amount += curbuf->b_ind_open_extra; + /* See remark above: "Only add b_ind_open_extra.." */ l = skipwhite(l); if (*l == '{') - amount -= ind_open_extra; + amount -= curbuf->b_ind_open_extra; lookfor = iscase ? LOOKFOR_ANY : LOOKFOR_TERM; /* @@ -8443,10 +8405,9 @@ && cin_iselse(l) && whilelevel == 0) { - if ((trypos = find_start_brace(ind_maxcomment)) - == NULL - || find_match(LOOKFOR_IF, trypos->lnum, - ind_maxparen, ind_maxcomment) == FAIL) + if ((trypos = find_start_brace()) == NULL + || find_match(LOOKFOR_IF, trypos->lnum) + == FAIL) break; continue; } @@ -8456,9 +8417,8 @@ * that block. */ l = ml_get_curline(); - if (find_last_paren(l, '{', '}') - && (trypos = find_start_brace(ind_maxcomment)) - != NULL) /* XXX */ + if (find_last_paren(l, '{', '}') /* XXX */ + && (trypos = find_start_brace()) != NULL) { curwin->w_cursor = *trypos; /* if not "else {" check for terminated again */ @@ -8477,11 +8437,11 @@ /* add extra indent for a comment */ if (cin_iscomment(theline)) - amount += ind_comment; + amount += curbuf->b_ind_comment; /* subtract extra left-shift for jump labels */ - if (ind_jump_label > 0 && original_line_islabel) - amount -= ind_jump_label; + if (curbuf->b_ind_jump_label > 0 && original_line_islabel) + amount -= curbuf->b_ind_jump_label; } /* @@ -8502,7 +8462,7 @@ if (theline[0] == '{') { - amount = ind_first_open; + amount = curbuf->b_ind_first_open; } /* @@ -8519,11 +8479,10 @@ && !cin_ends_in(theline, (char_u *)":", NULL) && !cin_ends_in(theline, (char_u *)",", NULL) && cin_isfuncdecl(NULL, cur_curpos.lnum + 1, - cur_curpos.lnum + 1, - ind_maxparen, ind_maxcomment) + cur_curpos.lnum + 1) && !cin_isterminated(theline, FALSE, TRUE)) { - amount = ind_func_type; + amount = curbuf->b_ind_func_type; } else { @@ -8542,7 +8501,7 @@ /* * If we're in a comment now, skip to the start of the comment. */ /* XXX */ - if ((trypos = find_start_comment(ind_maxcomment)) != NULL) + if ((trypos = ind_find_start_comment()) != NULL) { curwin->w_cursor.lnum = trypos->lnum + 1; curwin->w_cursor.col = 0; @@ -8554,7 +8513,7 @@ * constructor initialization? */ /* XXX */ n = FALSE; - if (ind_cpp_baseclass != 0 && theline[0] != '{') + if (curbuf->b_ind_cpp_baseclass != 0 && theline[0] != '{') { n = cin_is_cpp_baseclass(&col); l = ml_get_curline(); @@ -8562,8 +8521,7 @@ if (n) { /* XXX */ - amount = get_baseclass_amount(col, ind_maxparen, - ind_maxcomment, ind_cpp_baseclass); + amount = get_baseclass_amount(col); break; } @@ -8594,8 +8552,8 @@ { /* take us back to opening paren */ if (find_last_paren(l, '(', ')') - && (trypos = find_match_paren(ind_maxparen, - ind_maxcomment)) != NULL) + && (trypos = find_match_paren( + curbuf->b_ind_maxparen)) != NULL) curwin->w_cursor = *trypos; /* For a line ending in ',' that is a continuation line go @@ -8626,8 +8584,7 @@ * If the line looks like a function declaration, and we're * not in a comment, put it the left margin. */ - if (cin_isfuncdecl(NULL, cur_curpos.lnum, 0, - ind_maxparen, ind_maxcomment)) /* XXX */ + if (cin_isfuncdecl(NULL, cur_curpos.lnum, 0)) /* XXX */ break; l = ml_get_curline(); @@ -8675,10 +8632,9 @@ * line (and the ones that follow) needs to be indented as * parameters. */ - if (cin_isfuncdecl(&l, curwin->w_cursor.lnum, 0, - ind_maxparen, ind_maxcomment)) + if (cin_isfuncdecl(&l, curwin->w_cursor.lnum, 0)) { - amount = ind_param; + amount = curbuf->b_ind_param; break; } @@ -8707,8 +8663,7 @@ */ find_last_paren(l, '(', ')'); - if ((trypos = find_match_paren(ind_maxparen, - ind_maxcomment)) != NULL) + if ((trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL) curwin->w_cursor = *trypos; amount = get_indent(); /* XXX */ break; @@ -8716,7 +8671,7 @@ /* add extra indent for a comment */ if (cin_iscomment(theline)) - amount += ind_comment; + amount += curbuf->b_ind_comment; /* add extra indent if the previous line ended in a backslash: * "asdfasdf\ @@ -8751,11 +8706,9 @@ } static int -find_match(lookfor, ourscope, ind_maxparen, ind_maxcomment) +find_match(lookfor, ourscope) int lookfor; linenr_T ourscope; - int ind_maxparen; - int ind_maxcomment; { char_u *look; pos_T *theirscope; @@ -8785,13 +8738,13 @@ if (cin_iselse(look) || cin_isif(look) || cin_isdo(look) /* XXX */ - || cin_iswhileofdo(look, curwin->w_cursor.lnum, ind_maxparen)) + || cin_iswhileofdo(look, curwin->w_cursor.lnum)) { /* * if we've gone outside the braces entirely, * we must be out of scope... */ - theirscope = find_start_brace(ind_maxcomment); /* XXX */ + theirscope = find_start_brace(); /* XXX */ if (theirscope == NULL) break; @@ -8829,7 +8782,7 @@ * if it was a "while" then we need to go back to * another "do", so increment whilelevel. XXX */ - if (cin_iswhileofdo(look, curwin->w_cursor.lnum, ind_maxparen)) + if (cin_iswhileofdo(look, curwin->w_cursor.lnum)) { ++whilelevel; continue; @@ -9174,6 +9127,8 @@ /* * 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() @@ -9196,7 +9151,7 @@ { 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 */ @@ -9206,7 +9161,7 @@ ml_close_all(FALSE); /* close all memfiles, without deleting */ - OUT_STR(_("Vim: Finished.\n")); + OUT_STR("Vim: Finished.\n"); getout(1); } diff -ubBwrN ../../work/vim74/src/misc2.c ./src/misc2.c --- ../../work/vim74/src/misc2.c 2013-07-07 17:03:35.000000000 +0300 +++ ./src/misc2.c 2014-02-22 19:30:44.000000000 +0300 @@ -487,7 +487,7 @@ { while (lnum > cursor) { - (void)hasFolding(lnum, &lnum, NULL); + (void)hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL); /* if lnum and cursor are in the same fold, * now lnum <= cursor */ if (lnum > cursor) @@ -499,7 +499,7 @@ { while (lnum < cursor) { - (void)hasFolding(lnum, NULL, &lnum); + (void)hasFoldingWin(wp, lnum, NULL, &lnum, TRUE, NULL); /* if lnum and cursor are in the same fold, * now lnum >= cursor */ if (lnum < cursor) @@ -4695,8 +4695,8 @@ else { char_u *p = gettail(search_ctx->ffsc_fix_path); - char_u *wc_path = NUL; - char_u *temp = NUL; + char_u *wc_path = NULL; + char_u *temp = NULL; int len = 0; if (p > search_ctx->ffsc_fix_path) @@ -6496,13 +6496,15 @@ get4c(fd) FILE *fd; { - int n; - - n = getc(fd); - n = (n << 8) + getc(fd); - n = (n << 8) + getc(fd); - n = (n << 8) + getc(fd); - return n; + /* Use unsigned rather than int otherwise result is undefined + * when left-shift sets the MSB. */ + unsigned n; + + n = (unsigned)getc(fd); + n = (n << 8) + (unsigned)getc(fd); + n = (n << 8) + (unsigned)getc(fd); + n = (n << 8) + (unsigned)getc(fd); + return (int)n; } /* diff -ubBwrN ../../work/vim74/src/move.c ./src/move.c --- ../../work/vim74/src/move.c 2012-11-28 20:15:42.000000000 +0300 +++ ./src/move.c 2014-02-22 19:30:45.000000000 +0300 @@ -2101,6 +2101,9 @@ int used; lineoff_T loff; lineoff_T boff; +#ifdef FEAT_DIFF + linenr_T old_topline = curwin->w_topline; +#endif loff.lnum = boff.lnum = curwin->w_cursor.lnum; #ifdef FEAT_FOLDING @@ -2156,6 +2159,8 @@ curwin->w_topline = topline; #ifdef FEAT_DIFF curwin->w_topfill = topfill; + if (old_topline > curwin->w_topline + curwin->w_height) + curwin->w_botfill = FALSE; check_topfill(curwin, FALSE); #endif curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP); diff -ubBwrN ../../work/vim74/src/normal.c ./src/normal.c --- ../../work/vim74/src/normal.c 2013-07-14 14:24:37.000000000 +0300 +++ ./src/normal.c 2014-02-22 19:30:45.000000000 +0300 @@ -655,8 +655,8 @@ #ifdef FEAT_EVAL /* Set v:count here, when called from main() and not a stuffed * command, so that v:count can be used in an expression mapping - * when there is no count. */ - if (toplevel && stuff_empty()) + * when there is no count. Do set it for redo. */ + if (toplevel && readbuf1_empty()) set_vcount_ca(&ca, &set_prevcount); #endif @@ -736,8 +736,8 @@ #ifdef FEAT_EVAL /* Set v:count here, when called from main() and not a stuffed * command, so that v:count can be used in an expression mapping - * right after the count. */ - if (toplevel && stuff_empty()) + * right after the count. Do set it for redo. */ + if (toplevel && readbuf1_empty()) set_vcount_ca(&ca, &set_prevcount); #endif if (ctrl_w) @@ -819,8 +819,9 @@ #ifdef FEAT_EVAL /* * Only set v:count when called from main() and not a stuffed command. + * Do set it for redo. */ - if (toplevel && stuff_empty()) + if (toplevel && readbuf1_empty()) set_vcount(ca.count0, ca.count1, set_prevcount); #endif @@ -962,11 +963,8 @@ #ifdef FEAT_CMDL_INFO need_flushbuf |= add_to_showcmd(ca.nchar); #endif - /* For "gn" from redo, need to get one more char to determine the - * operator */ if (ca.nchar == 'r' || ca.nchar == '\'' || ca.nchar == '`' - || ca.nchar == Ctrl_BSL - || ((ca.nchar == 'n' || ca.nchar == 'N') && !stuff_empty())) + || ca.nchar == Ctrl_BSL) { cp = &ca.extra_char; /* need to get a third character */ if (ca.nchar != 'r') @@ -1797,10 +1795,9 @@ * otherwise it might be the second char of the operator. */ if (cap->cmdchar == 'g' && (cap->nchar == 'n' || cap->nchar == 'N')) - /* "gn" and "gN" are a bit different */ - prep_redo(oap->regname, 0L, NUL, cap->cmdchar, cap->nchar, - get_op_char(oap->op_type), - get_extra_op_char(oap->op_type)); + prep_redo(oap->regname, cap->count0, + get_op_char(oap->op_type), get_extra_op_char(oap->op_type), + oap->motion_force, cap->cmdchar, cap->nchar); else if (cap->cmdchar != ':') prep_redo(oap->regname, 0L, NUL, 'v', get_op_char(oap->op_type), @@ -4025,6 +4022,8 @@ #endif p = transchar(c); + if (*p == ' ') + STRCPY(p, "<20>"); old_len = (int)STRLEN(showcmd_buf); extra_len = (int)STRLEN(p); overflow = old_len + extra_len - SHOWCMD_COLS; @@ -4646,6 +4645,9 @@ } #endif + if (virtual_active() && atend) + coladvance(MAXCOL); + else coladvance(curwin->w_curswant); #if defined(FEAT_LINEBREAK) || defined(FEAT_MBYTE) @@ -5246,8 +5248,12 @@ { 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; @@ -7032,6 +7038,13 @@ { if (got_int) reset_VIsual(); + if (had_ctrl_v) + { + if (cap->nchar == '\r') + cap->nchar = -1; + else if (cap->nchar == '\n') + cap->nchar = -2; + } nv_operator(cap); return; } @@ -9518,6 +9531,8 @@ /* cursor is at the end of the line or end of file, put * forward. */ dir = FORWARD; + /* May have been reset in do_put(). */ + VIsual_active = TRUE; } #endif do_put(cap->oap->regname, dir, cap->count1, flags); diff -ubBwrN ../../work/vim74/src/ops.c ./src/ops.c --- ../../work/vim74/src/ops.c 2013-08-09 20:34:32.000000000 +0300 +++ ./src/ops.c 2014-02-22 19:30:45.000000000 +0300 @@ -336,7 +336,7 @@ { int count; int i, j; - int p_sw = (int)get_sw_value(); + int p_sw = (int)get_sw_value(curbuf); count = get_indent(); /* get current indent */ @@ -392,7 +392,7 @@ int total; char_u *newp, *oldp; int oldcol = curwin->w_cursor.col; - int p_sw = (int)get_sw_value(); + int p_sw = (int)get_sw_value(curbuf); int p_ts = (int)curbuf->b_p_ts; struct block_def bd; int incr; @@ -2074,10 +2074,15 @@ char_u *newp, *oldp; size_t oldlen; struct block_def bd; + char_u *after_p = NULL; + int had_ctrl_v_cr = (c == -1 || c == -2); if ((curbuf->b_ml.ml_flags & ML_EMPTY ) || oap->empty) return OK; /* nothing to do */ + if (had_ctrl_v_cr) + c = (c == -1 ? '\r' : '\n'); + #ifdef FEAT_MBYTE if (has_mbyte) mb_adjust_opend(oap); @@ -2164,6 +2169,9 @@ /* insert pre-spaces */ copy_spaces(newp + bd.textcol, (size_t)bd.startspaces); /* insert replacement chars CHECK FOR ALLOCATED SPACE */ + /* -1/-2 is used for entering CR literally. */ + if (had_ctrl_v_cr || (c != '\r' && c != '\n')) + { #ifdef FEAT_MBYTE if (has_mbyte) { @@ -2181,8 +2189,24 @@ /* copy the part after the changed part */ STRMOVE(newp + STRLEN(newp), oldp); } + } + else + { + /* Replacing with \r or \n means splitting the line. */ + after_p = alloc_check( + (unsigned)(oldlen + 1 + n - STRLEN(newp))); + if (after_p != NULL) + STRMOVE(after_p, oldp); + } /* replace the line */ ml_replace(curwin->w_cursor.lnum, newp, FALSE); + if (after_p != NULL) + { + ml_append(curwin->w_cursor.lnum++, after_p, 0, FALSE); + appended_lines_mark(curwin->w_cursor.lnum, 1L); + oap->end.lnum++; + vim_free(after_p); + } } } else @@ -2617,6 +2641,31 @@ { struct block_def bd2; + /* The user may have moved the cursor before inserting something, try + * to adjust the block for that. */ + if (oap->start.lnum == curbuf->b_op_start.lnum && !bd.is_MAX) + { + if (oap->op_type == OP_INSERT + && oap->start.col != curbuf->b_op_start.col) + { + oap->start.col = curbuf->b_op_start.col; + pre_textlen -= getviscol2(oap->start.col, oap->start.coladd) + - oap->start_vcol; + oap->start_vcol = getviscol2(oap->start.col, oap->start.coladd); + } + else if (oap->op_type == OP_APPEND + && oap->end.col >= curbuf->b_op_start.col) + { + oap->start.col = curbuf->b_op_start.col; + /* reset pre_textlen to the value of OP_INSERT */ + pre_textlen += bd.textlen; + pre_textlen -= getviscol2(oap->start.col, oap->start.coladd) + - oap->start_vcol; + oap->start_vcol = getviscol2(oap->start.col, oap->start.coladd); + oap->op_type = OP_INSERT; + } + } + /* * Spaces and tabs in the indent may have changed to other spaces and * tabs. Get the starting column again and correct the length. @@ -3776,13 +3825,14 @@ */ if (y_type == MCHAR && y_size == 1) { + do { totlen = count * yanklen; - if (totlen) + if (totlen > 0) { oldp = ml_get(lnum); newp = alloc_check((unsigned)(STRLEN(oldp) + totlen + 1)); if (newp == NULL) - goto end; /* alloc() will give error message */ + goto end; /* alloc() gave an error message */ mch_memmove(newp, oldp, (size_t)col); ptr = newp + col; for (i = 0; i < count; ++i) @@ -3792,9 +3842,26 @@ } STRMOVE(ptr, oldp + col); ml_replace(lnum, newp, FALSE); - /* Put cursor on last putted char. */ + /* Place cursor on last putted char. */ + if (lnum == curwin->w_cursor.lnum) + { + /* make sure curwin->w_virtcol is updated */ + changed_cline_bef_curs(); curwin->w_cursor.col += (colnr_T)(totlen - 1); } + } +#ifdef FEAT_VISUAL + if (VIsual_active) + lnum++; +#endif + } while ( +#ifdef FEAT_VISUAL + VIsual_active && lnum <= curbuf->b_visual.vi_end.lnum +#else + FALSE /* stop after 1 paste */ +#endif + ); + curbuf->b_op_end = curwin->w_cursor; /* For "CTRL-O p" in Insert mode, put cursor after last char */ if (totlen && (restart_edit != 0 || (flags & PUT_CURSEND))) @@ -3955,6 +4022,10 @@ 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(); } @@ -4005,7 +4076,8 @@ # endif # endif # ifdef FEAT_CINDENT - (curbuf->b_p_cin && in_cinkeys('#', ' ', TRUE)) + (curbuf->b_p_cin && in_cinkeys('#', ' ', TRUE) + && curbuf->b_ind_hash_comment == 0) # endif ; } @@ -4380,6 +4452,12 @@ for (t = 0; t < count; ++t) { curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t)); + if (t == 0) + { + /* Set the '[ mark. */ + curwin->w_buffer->b_op_start.lnum = curwin->w_cursor.lnum; + curwin->w_buffer->b_op_start.col = (colnr_T)STRLEN(curr); + } #if defined(FEAT_COMMENTS) || defined(PROTO) if (remove_comments) { @@ -4496,6 +4574,10 @@ } ml_replace(curwin->w_cursor.lnum, newp, FALSE); + /* Set the '] mark. */ + curwin->w_buffer->b_op_end.lnum = curwin->w_cursor.lnum; + curwin->w_buffer->b_op_end.col = (colnr_T)STRLEN(newp); + /* Only report the change in the first line here, del_lines() will report * the deleted line. */ changed_lines(curwin->w_cursor.lnum, currsize, @@ -4971,7 +5053,7 @@ /* * When still in same paragraph, join the lines together. But - * first delete the comment leader from the second line. + * first delete the leader from the second line. */ if (!is_end_par) { @@ -4981,11 +5063,25 @@ if (line_count < 0 && u_save_cursor() == FAIL) break; #ifdef FEAT_COMMENTS - (void)del_bytes((long)next_leader_len, FALSE, FALSE); if (next_leader_len > 0) + { + (void)del_bytes((long)next_leader_len, FALSE, FALSE); mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L, (long)-next_leader_len); + } else #endif + if (second_indent > 0) /* the "leader" for FO_Q_SECOND */ + { + char_u *p = ml_get_curline(); + int indent = (int)(skipwhite(p) - p); + + if (indent > 0) + { + (void)del_bytes(indent, FALSE, FALSE); + mark_col_adjust(curwin->w_cursor.lnum, + (colnr_T)0, 0L, (long)-indent); + } + } curwin->w_cursor.lnum--; if (do_join(2, TRUE, FALSE, FALSE) == FAIL) { @@ -6154,7 +6250,9 @@ regname = may_get_selection(regname); #endif - /* Should we check for a valid name? */ + if (regname != NUL && !valid_yank_reg(regname, FALSE)) + return MAUTO; + get_yank_register(regname, FALSE); if (y_current->y_array != NULL) diff -ubBwrN ../../work/vim74/src/option.c ./src/option.c --- ../../work/vim74/src/option.c 2013-07-17 22:39:13.000000000 +0300 +++ ./src/option.c 2014-02-22 19:30:45.000000000 +0300 @@ -234,6 +234,7 @@ #ifdef FEAT_STL_OPT # define PV_STL OPT_BOTH(OPT_WIN(WV_STL)) #endif +#define PV_UL OPT_BOTH(OPT_BUF(BV_UL)) #ifdef FEAT_WINDOWS # define PV_WFH OPT_WIN(WV_WFH) #endif @@ -2683,7 +2684,7 @@ #endif {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT}, {"undolevels", "ul", P_NUM|P_VI_DEF, - (char_u *)&p_ul, PV_NONE, + (char_u *)&p_ul, PV_UL, { #if defined(UNIX) || defined(WIN3264) || defined(OS2) || defined(VMS) (char_u *)1000L, @@ -3313,6 +3314,7 @@ curbuf->b_p_initialized = TRUE; curbuf->b_p_ar = -1; /* no local 'autoread' value */ + curbuf->b_p_ul = NO_LOCAL_UNDOLEVEL; check_buf_options(curbuf); check_win_options(curwin); check_options(); @@ -4512,8 +4514,16 @@ ((flags & P_VI_DEF) || cp_val) ? VI_DEFAULT : VIM_DEFAULT]; else if (nextchar == '<') - value = *(long *)get_varp_scope(&(options[opt_idx]), - OPT_GLOBAL); + { + /* For 'undolevels' NO_LOCAL_UNDOLEVEL means to + * use the global value. */ + if ((long *)varp == &curbuf->b_p_ul + && opt_flags == OPT_LOCAL) + value = NO_LOCAL_UNDOLEVEL; + else + value = *(long *)get_varp_scope( + &(options[opt_idx]), OPT_GLOBAL); + } else if (((long *)varp == &p_wc || (long *)varp == &p_wcm) && (*arg == '<' @@ -5372,6 +5382,7 @@ #ifdef FEAT_CINDENT check_string_option(&buf->b_p_cink); check_string_option(&buf->b_p_cino); + parse_cino(buf); #endif #ifdef FEAT_AUTOCMD check_string_option(&buf->b_p_ft); @@ -6990,6 +7001,15 @@ } #endif +#ifdef FEAT_CINDENT + /* 'cinoptions' */ + else if (gvarp == &p_cino) + { + /* TODO: recognize errors */ + parse_cino(curbuf); + } +#endif + /* Options that are a list of flags. */ else { @@ -7102,6 +7122,11 @@ if (varp == &(curwin->w_s->b_p_spl)) { char_u fname[200]; + char_u *q = curwin->w_s->b_p_spl; + + /* Skip the first name if it is "cjk". */ + if (STRNCMP(q, "cjk,", 4) == 0) + q += 4; /* * Source the spell/LANG.vim in 'runtimepath'. @@ -7109,11 +7134,10 @@ * Use the first name in 'spelllang' up to '_region' or * '.encoding'. */ - for (p = curwin->w_s->b_p_spl; *p != NUL; ++p) + for (p = q; *p != NUL; ++p) if (vim_strchr((char_u *)"_.,", *p) != NULL) break; - vim_snprintf((char *)fname, 200, "spell/%.*s.vim", - (int)(p - curwin->w_s->b_p_spl), curwin->w_s->b_p_spl); + vim_snprintf((char *)fname, 200, "spell/%.*s.vim", (int)(p - q), q); source_runtime(fname, TRUE); } #endif @@ -7791,7 +7815,7 @@ /* when 'hlsearch' is set or reset: reset no_hlsearch */ else if ((int *)varp == &p_hls) { - no_hlsearch = FALSE; + SET_NO_HLSEARCH(FALSE); } #endif @@ -8338,14 +8362,24 @@ curwin->w_p_fdc = 12; } } +#endif /* FEAT_FOLDING */ +#if defined(FEAT_FOLDING) || defined(FEAT_CINDENT) /* 'shiftwidth' or 'tabstop' */ else if (pp == &curbuf->b_p_sw || pp == &curbuf->b_p_ts) { +# ifdef FEAT_FOLDING if (foldmethodIsIndent(curwin)) foldUpdateAll(curwin); +# endif +# ifdef FEAT_CINDENT + /* When 'shiftwidth' changes, or it's zero and 'tabstop' changes: + * parse 'cinoptions'. */ + if (pp == &curbuf->b_p_sw || curbuf->b_p_sw == 0) + parse_cino(curbuf); +# endif } -#endif /* FEAT_FOLDING */ +#endif #ifdef FEAT_MBYTE /* 'maxcombine' */ @@ -8467,6 +8501,13 @@ u_sync(TRUE); p_ul = value; } + else if (pp == &curbuf->b_p_ul) + { + /* use the old value, otherwise u_sync() may not work properly */ + curbuf->b_p_ul = old_value; + u_sync(TRUE); + curbuf->b_p_ul = value; + } #ifdef FEAT_LINEBREAK /* 'numberwidth' must be positive */ @@ -8820,7 +8861,7 @@ } #endif -#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) +#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO) /* * Returns the option attributes and its value. Unlike the above function it * will return either global value or local value of the option depending on @@ -8833,7 +8874,8 @@ * opt_type). Uses * * Returned flags: - * 0 hidden or unknown option + * 0 hidden or unknown option, also option that does not have requested + * type (see SREQ_* in vim.h) * see SOPT_* in vim.h for other flags * * Possible opt_type values: see SREQ_* in vim.h @@ -8956,6 +8998,68 @@ return r; } + +/* + * Iterate over options. First argument is a pointer to a pointer to a structure + * inside options[] array, second is option type like in the above function. + * + * If first argument points to NULL it is assumed that iteration just started + * and caller needs the very first value. + * If first argument points to the end marker function returns NULL and sets + * first argument to NULL. + * + * Returns full option name for current option on each call. + */ + char_u * +option_iter_next(option, opt_type) + void **option; + int opt_type; +{ + struct vimoption *ret = NULL; + do + { + if (*option == NULL) + *option = (void *) options; + else if (((struct vimoption *) (*option))->fullname == NULL) + { + *option = NULL; + return NULL; + } + else + *option = (void *) (((struct vimoption *) (*option)) + 1); + + ret = ((struct vimoption *) (*option)); + + /* Hidden option */ + if (ret->var == NULL) + { + ret = NULL; + continue; + } + + switch (opt_type) + { + case SREQ_GLOBAL: + if (!(ret->indir == PV_NONE || ret->indir & PV_BOTH)) + ret = NULL; + break; + case SREQ_BUF: + if (!(ret->indir & PV_BUF)) + ret = NULL; + break; + case SREQ_WIN: + if (!(ret->indir & PV_WIN)) + ret = NULL; + break; + default: + EMSG2(_(e_intern2), "option_iter_next()"); + return NULL; + } + } + while (ret == NULL); + + return (char_u *)ret->fullname; +} #endif /* @@ -9773,6 +9876,9 @@ clear_string_option(&((win_T *)from)->w_p_stl); break; #endif + case PV_UL: + buf->b_p_ul = NO_LOCAL_UNDOLEVEL; + break; } } @@ -9821,6 +9927,7 @@ #ifdef FEAT_STL_OPT case PV_STL: return (char_u *)&(curwin->w_p_stl); #endif + case PV_UL: return (char_u *)&(curbuf->b_p_ul); } return NULL; /* "cannot happen" */ } @@ -9885,6 +9992,8 @@ case PV_STL: return *curwin->w_p_stl != NUL ? (char_u *)&(curwin->w_p_stl) : p->var; #endif + case PV_UL: return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL + ? (char_u *)&(curbuf->b_p_ul) : p->var; #ifdef FEAT_ARABIC case PV_ARAB: return (char_u *)&(curwin->w_p_arab); @@ -10425,6 +10534,7 @@ /* options that are normally global but also have a local value * are not copied, start using the global value */ buf->b_p_ar = -1; + buf->b_p_ul = NO_LOCAL_UNDOLEVEL; #ifdef FEAT_QUICKFIX buf->b_p_gp = empty_option; buf->b_p_mp = empty_option; @@ -11729,9 +11839,10 @@ * 'tabstop' value when 'shiftwidth' is zero. */ long -get_sw_value() +get_sw_value(buf) + buf_T *buf; { - return curbuf->b_p_sw ? curbuf->b_p_sw : curbuf->b_p_ts; + return buf->b_p_sw ? buf->b_p_sw : buf->b_p_ts; } /* @@ -11741,7 +11852,7 @@ long get_sts_value() { - return curbuf->b_p_sts < 0 ? get_sw_value() : curbuf->b_p_sts; + return curbuf->b_p_sts < 0 ? get_sw_value(curbuf) : curbuf->b_p_sts; } /* diff -ubBwrN ../../work/vim74/src/option.h ./src/option.h --- ../../work/vim74/src/option.h 2013-06-26 19:41:39.000000000 +0300 +++ ./src/option.h 2014-02-22 19:30:44.000000000 +0300 @@ -31,9 +31,9 @@ # define DFLT_EFM "%A%p^,%C%%CC-%t-%m,%Cat line number %l in file %f,%f|%l| %m" # else /* Unix, probably */ # ifdef EBCDIC -#define DFLT_EFM "%*[^ ] %*[^ ] %f:%l%*[ ]%m,%*[^\"]\"%f\"%*\\D%l: %m,\"%f\"%*\\D%l: %m,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,\"%f\"\\, line %l%*\\D%c%*[^ ] %m,%D%*\\a[%*\\d]: Entering directory `%f',%X%*\\a[%*\\d]: Leaving directory `%f',%DMaking %*\\a in %f,%f|%l| %m" +#define DFLT_EFM "%*[^ ] %*[^ ] %f:%l%*[ ]%m,%*[^\"]\"%f\"%*\\D%l: %m,\"%f\"%*\\D%l: %m,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,\"%f\"\\, line %l%*\\D%c%*[^ ] %m,%D%*\\a[%*\\d]: Entering directory %*[`']%f',%X%*\\a[%*\\d]: Leaving directory %*[`']%f',%DMaking %*\\a in %f,%f|%l| %m" # else -#define DFLT_EFM "%*[^\"]\"%f\"%*\\D%l: %m,\"%f\"%*\\D%l: %m,%-G%f:%l: (Each undeclared identifier is reported only once,%-G%f:%l: for each function it appears in.),%-GIn file included from %f:%l:%c:,%-GIn file included from %f:%l:%c\\,,%-GIn file included from %f:%l:%c,%-GIn file included from %f:%l,%-G%*[ ]from %f:%l:%c,%-G%*[ ]from %f:%l:,%-G%*[ ]from %f:%l\\,,%-G%*[ ]from %f:%l,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,\"%f\"\\, line %l%*\\D%c%*[^ ] %m,%D%*\\a[%*\\d]: Entering directory `%f',%X%*\\a[%*\\d]: Leaving directory `%f',%D%*\\a: Entering directory `%f',%X%*\\a: Leaving directory `%f',%DMaking %*\\a in %f,%f|%l| %m" +#define DFLT_EFM "%*[^\"]\"%f\"%*\\D%l: %m,\"%f\"%*\\D%l: %m,%-G%f:%l: (Each undeclared identifier is reported only once,%-G%f:%l: for each function it appears in.),%-GIn file included from %f:%l:%c:,%-GIn file included from %f:%l:%c\\,,%-GIn file included from %f:%l:%c,%-GIn file included from %f:%l,%-G%*[ ]from %f:%l:%c,%-G%*[ ]from %f:%l:,%-G%*[ ]from %f:%l\\,,%-G%*[ ]from %f:%l,%f:%l:%c:%m,%f(%l):%m,%f:%l:%m,\"%f\"\\, line %l%*\\D%c%*[^ ] %m,%D%*\\a[%*\\d]: Entering directory %*[`']%f',%X%*\\a[%*\\d]: Leaving directory %*[`']%f',%D%*\\a: Entering directory %*[`']%f',%X%*\\a: Leaving directory %*[`']%f',%DMaking %*\\a in %f,%f|%l| %m" # endif # endif # endif @@ -1031,6 +1031,7 @@ , BV_TW , BV_TX , BV_UDF + , BV_UL , BV_WM , BV_COUNT /* must be the last one */ }; @@ -1109,3 +1110,6 @@ , WV_WRAP , WV_COUNT /* must be the last one */ }; + +/* Value for b_p_ul indicating the global value must be used. */ +#define NO_LOCAL_UNDOLEVEL -123456 diff -ubBwrN ../../work/vim74/src/os_dos.h ./src/os_dos.h --- ../../work/vim74/src/os_dos.h 2013-06-12 21:09:44.000000000 +0300 +++ ./src/os_dos.h 2014-02-22 19:30:43.000000000 +0300 @@ -109,7 +109,7 @@ #endif #ifndef DFLT_BDIR -# define DFLT_BDIR ".,c:\\tmp,c:\\temp" /* default for 'backupdir' */ +# define DFLT_BDIR ".,$TEMP,c:\\tmp,c:\\temp" /* default for 'backupdir' */ #endif #ifndef DFLT_VDIR @@ -117,7 +117,7 @@ #endif #ifndef DFLT_DIR -# define DFLT_DIR ".,c:\\tmp,c:\\temp" /* default for 'directory' */ +# define DFLT_DIR ".,$TEMP,c:\\tmp,c:\\temp" /* default for 'directory' */ #endif #define DFLT_ERRORFILE "errors.err" diff -ubBwrN ../../work/vim74/src/os_mac.h ./src/os_mac.h --- ../../work/vim74/src/os_mac.h 2013-05-06 05:06:04.000000000 +0300 +++ ./src/os_mac.h 2014-02-22 19:30:41.000000000 +0300 @@ -16,6 +16,11 @@ # define OPAQUE_TOOLBOX_STRUCTS 0 #endif +/* Include MAC_OS_X_VERSION_* macros */ +#ifdef HAVE_AVAILABILITYMACROS_H +# include +#endif + /* * Macintosh machine-dependent things. * @@ -263,7 +268,7 @@ #endif /* Some "prep work" definition to be able to compile the MacOS X - * version with os_unix.x instead of os_mac.c. Based on the result + * version with os_unix.c instead of os_mac.c. Based on the result * of ./configure for console MacOS X. */ diff -ubBwrN ../../work/vim74/src/os_mswin.c ./src/os_mswin.c --- ../../work/vim74/src/os_mswin.c 2013-06-16 17:41:11.000000000 +0300 +++ ./src/os_mswin.c 2014-02-22 19:30:45.000000000 +0300 @@ -456,7 +456,14 @@ int mch_isFullName(char_u *fname) { +#ifdef FEAT_MBYTE + /* WinNT and later can use _MAX_PATH wide characters for a pathname, which + * means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is + * UTF-8. */ + char szName[_MAX_PATH * 3 + 1]; +#else char szName[_MAX_PATH + 1]; +#endif /* A name like "d:/foo" and "//server/share" is absolute */ if ((fname[0] && fname[1] == ':' && (fname[2] == '/' || fname[2] == '\\')) @@ -464,7 +471,7 @@ return TRUE; /* A name that can't be made absolute probably isn't absolute. */ - if (mch_FullName(fname, szName, _MAX_PATH, FALSE) == FAIL) + if (mch_FullName(fname, szName, sizeof(szName) - 1, FALSE) == FAIL) return FALSE; return pathcmp(fname, szName, -1) == 0; @@ -491,6 +498,104 @@ } } +#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__) +# 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. @@ -498,15 +603,36 @@ int vim_stat(const char *name, struct stat *stp) { +#ifdef FEAT_MBYTE + /* WinNT and later can use _MAX_PATH wide characters for a pathname, which + * means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is + * UTF-8. */ + char buf[_MAX_PATH * 3 + 1]; +#else char buf[_MAX_PATH + 1]; +#endif char *p; - vim_strncpy((char_u *)buf, (char_u *)name, _MAX_PATH); + vim_strncpy((char_u *)buf, (char_u *)name, sizeof(buf) - 1); p = buf + strlen(buf); if (p > buf) mb_ptr_back(buf, p); + + /* Remove trailing '\\' except root path. */ if (p > buf && (*p == '\\' || *p == '/') && p[-1] != ':') *p = NUL; + + if ((buf[0] == '\\' && buf[1] == '\\') || (buf[0] == '/' && buf[1] == '/')) + { + /* UNC root path must be followed by '\\'. */ + p = vim_strpbrk(buf + 2, "\\/"); + if (p != NULL) + { + p = vim_strpbrk(p + 1, "\\/"); + if (p == NULL) + STRCAT(buf, "\\"); + } + } #ifdef FEAT_MBYTE if (enc_codepage >= 0 && (int)GetACP() != enc_codepage # ifdef __BORLANDC__ @@ -520,9 +646,9 @@ if (wp != NULL) { - n = _wstat(wp, (struct _stat *)stp); + n = wstat_symlink_aware(wp, (struct _stat *)stp); vim_free(wp); - if (n >= 0) + if (n >= 0 || g_PlatformId == VER_PLATFORM_WIN32_NT) return n; /* Retry with non-wide function (for Windows 98). Can't use * GetLastError() here and it's unclear what errno gets set to if @@ -530,7 +656,7 @@ } } #endif - return stat(buf, stp); + return stat_symlink_aware(buf, stp); } #if defined(FEAT_GUI_MSWIN) || defined(PROTO) @@ -689,8 +815,8 @@ { n = _wchdir(p); vim_free(p); - if (n == 0) - return 0; + if (n == 0 || g_PlatformId == VER_PLATFORM_WIN32_NT) + return n; /* Retry with non-wide function (for Windows 98). */ } } @@ -1761,9 +1887,13 @@ IPersistFile *ppf = NULL; OLECHAR wsz[MAX_PATH]; WIN32_FIND_DATA ffd; // we get those free of charge - TCHAR buf[MAX_PATH]; // could have simply reused 'wsz'... + CHAR buf[MAX_PATH]; // could have simply reused 'wsz'... char_u *rfname = NULL; int len; +# ifdef FEAT_MBYTE + IShellLinkW *pslw = NULL; + WIN32_FIND_DATAW ffdw; // we get those free of charge +# endif /* Check if the file name ends in ".lnk". Avoid calling * CoCreateInstance(), it's quite slow. */ @@ -1775,18 +1905,61 @@ CoInitialize(NULL); +# ifdef FEAT_MBYTE + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { + // create a link manager object and request its interface + hr = CoCreateInstance( + &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, + &IID_IShellLinkW, (void**)&pslw); + if (hr == S_OK) + { + WCHAR *p = enc_to_utf16(fname, NULL); + + if (p != NULL) + { + // Get a pointer to the IPersistFile interface. + hr = pslw->lpVtbl->QueryInterface( + pslw, &IID_IPersistFile, (void**)&ppf); + if (hr != S_OK) + goto shortcut_errorw; + + // "load" the name and resolve the link + hr = ppf->lpVtbl->Load(ppf, p, STGM_READ); + if (hr != S_OK) + goto shortcut_errorw; +# if 0 // This makes Vim wait a long time if the target does not exist. + hr = pslw->lpVtbl->Resolve(pslw, NULL, SLR_NO_UI); + if (hr != S_OK) + goto shortcut_errorw; +# endif + + // Get the path to the link target. + ZeroMemory(wsz, MAX_PATH * sizeof(WCHAR)); + hr = pslw->lpVtbl->GetPath(pslw, wsz, MAX_PATH, &ffdw, 0); + if (hr == S_OK && wsz[0] != NUL) + rfname = utf16_to_enc(wsz, NULL); + +shortcut_errorw: + vim_free(p); + goto shortcut_end; + } + } + /* Retry with non-wide function (for Windows 98). */ + } +# endif // create a link manager object and request its interface hr = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, (void**)&psl); if (hr != S_OK) - goto shortcut_error; + goto shortcut_end; // Get a pointer to the IPersistFile interface. hr = psl->lpVtbl->QueryInterface( psl, &IID_IPersistFile, (void**)&ppf); if (hr != S_OK) - goto shortcut_error; + goto shortcut_end; // full path string must be in Unicode. MultiByteToWideChar(CP_ACP, 0, fname, -1, wsz, MAX_PATH); @@ -1794,11 +1967,11 @@ // "load" the name and resolve the link hr = ppf->lpVtbl->Load(ppf, wsz, STGM_READ); if (hr != S_OK) - goto shortcut_error; + goto shortcut_end; #if 0 // This makes Vim wait a long time if the target doesn't exist. hr = psl->lpVtbl->Resolve(psl, NULL, SLR_NO_UI); if (hr != S_OK) - goto shortcut_error; + goto shortcut_end; #endif // Get the path to the link target. @@ -1807,12 +1980,16 @@ if (hr == S_OK && buf[0] != NUL) rfname = vim_strsave(buf); -shortcut_error: +shortcut_end: // Release all interface pointers (both belong to the same object) if (ppf != NULL) ppf->lpVtbl->Release(ppf); if (psl != NULL) psl->lpVtbl->Release(psl); +# ifdef FEAT_MBYTE + if (pslw != NULL) + pslw->lpVtbl->Release(pslw); +# endif CoUninitialize(); return rfname; diff -ubBwrN ../../work/vim74/src/os_unix.c ./src/os_unix.c --- ../../work/vim74/src/os_unix.c 2013-07-03 17:32:32.000000000 +0300 +++ ./src/os_unix.c 2014-02-22 19:30:44.000000000 +0300 @@ -168,7 +168,7 @@ static pid_t wait4pid __ARGS((pid_t, waitstatus *)); static int WaitForChar __ARGS((long)); -#if defined(__BEOS__) +#if defined(__BEOS__) || defined(VMS) int RealWaitForChar __ARGS((int, long, int *)); #else static int RealWaitForChar __ARGS((int, long, int *)); @@ -435,7 +435,6 @@ /* Process the queued netbeans messages. */ netbeans_parse_messages(); #endif -#ifndef VMS /* VMS: must try reading, WaitForChar() does nothing. */ /* * We want to be interrupted by the winch signal * or by an event on the monitored file descriptors. @@ -446,7 +445,6 @@ handle_resize(); return 0; } -#endif /* If input was put directly in typeahead buffer bail out here. */ if (typebuf_changed(tb_change_cnt)) @@ -804,6 +802,10 @@ * completely full. */ +#if defined(HAVE_AVAILABILITYMACROS_H) +# include +#endif + #ifndef SIGSTKSZ # define SIGSTKSZ 8000 /* just a guess of how much stack is needed... */ #endif @@ -957,8 +959,10 @@ /* * 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 +1094,23 @@ } 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(); @@ -5028,6 +5037,7 @@ return avail; } +#ifndef VMS /* * Wait "msec" msec until a character is available from file descriptor "fd". * "msec" == 0 will check for characters once. @@ -5327,13 +5337,7 @@ } # endif -# ifdef OLD_VMS - /* Old VMS as v6.2 and older have broken select(). It waits more than - * required. Should not be used */ - ret = 0; -# else ret = select(maxfd + 1, &rfds, NULL, &efds, tvp); -# endif # ifdef EINTR if (ret == -1 && errno == EINTR) { @@ -5455,8 +5459,6 @@ return (ret > 0); } -#ifndef VMS - #ifndef NO_EXPANDPATH /* * Expand a path into all matching files and/or directories. Handles "*", @@ -5979,7 +5981,7 @@ { /* If there is a NUL, set did_find_nul, else set check_spaces */ buffer[len] = NUL; - if (len && (int)STRLEN(buffer) < (int)len - 1) + if (len && (int)STRLEN(buffer) < (int)len) did_find_nul = TRUE; else check_spaces = TRUE; diff -ubBwrN ../../work/vim74/src/os_unix.h ./src/os_unix.h --- ../../work/vim74/src/os_unix.h 2013-06-12 21:09:44.000000000 +0300 +++ ./src/os_unix.h 2014-02-22 19:30:44.000000000 +0300 @@ -225,6 +225,8 @@ # include # include # include +# include +# include # ifdef FEAT_GUI_GTK # include "gui_gtk_vms.h" diff -ubBwrN ../../work/vim74/src/os_vms.c ./src/os_vms.c --- ../../work/vim74/src/os_vms.c 2010-06-26 07:03:31.000000000 +0300 +++ ./src/os_vms.c 2014-02-22 19:30:44.000000000 +0300 @@ -11,6 +11,23 @@ #include "vim.h" +/* define _generic_64 for use in time functions */ +#ifndef VAX +# include +#else +/* based on Alpha's gen64def.h; the file is absent on VAX */ +typedef struct _generic_64 { +# pragma __nomember_alignment + __union { /* You can treat me as... */ + /* long long is not available on VAXen */ + /* unsigned __int64 gen64$q_quadword; ...a single 64-bit value, or */ + + unsigned int gen64$l_longword [2]; /* ...two 32-bit values, or */ + unsigned short int gen64$w_word [4]; /* ...four 16-bit values */ + } gen64$r_quad_overlay; +} GENERIC_64; +#endif + typedef struct { char class; @@ -669,3 +686,92 @@ } return ; } + +struct typeahead_st { + unsigned short numchars; + unsigned char firstchar; + unsigned char reserved0; + unsigned long reserved1; +} typeahead; + +/* + * Wait "msec" msec until a character is available from file descriptor "fd". + * "msec" == 0 will check for characters once. + * "msec" == -1 will block until a character is available. + */ + int +RealWaitForChar(fd, msec, check_for_gpm) + int fd UNUSED; /* always read from iochan */ + long msec; + int *check_for_gpm UNUSED; +{ + int status; + struct _generic_64 time_curr; + struct _generic_64 time_diff; + struct _generic_64 time_out; + unsigned int convert_operation = LIB$K_DELTA_SECONDS_F; + float sec = (float) msec / 1000; + + /* make sure the iochan is set */ + if (!iochan) + get_tty(); + + if (msec > 0) { + /* time-out specified; convert it to absolute time */ + + /* get current time (number of 100ns ticks since the VMS Epoch) */ + status = sys$gettim(&time_curr); + if (status != SS$_NORMAL) + return 0; /* error */ + + /* construct the delta time */ + status = lib$cvtf_to_internal_time( + &convert_operation, &sec, &time_diff); + if (status != LIB$_NORMAL) + return 0; /* error */ + + /* add them up */ + status = lib$add_times( + &time_curr, + &time_diff, + &time_out); + if (status != LIB$_NORMAL) + return 0; /* error */ + } + + while (TRUE) { + /* select() */ + status = sys$qiow(0, iochan, IO$_SENSEMODE | IO$M_TYPEAHDCNT, iosb, + 0, 0, &typeahead, 8, 0, 0, 0, 0); + if (status != SS$_NORMAL || (iosb[0] & 0xFFFF) != SS$_NORMAL) + return 0; /* error */ + + if (typeahead.numchars) + return 1; /* ready to read */ + + /* there's nothing to read; what now? */ + if (msec == 0) { + /* immediate time-out; return impatiently */ + return 0; + } + else if (msec < 0) { + /* no time-out; wait on indefinitely */ + continue; + } + else { + /* time-out needs to be checked */ + status = sys$gettim(&time_curr); + if (status != SS$_NORMAL) + return 0; /* error */ + + status = lib$sub_times( + &time_out, + &time_curr, + &time_diff); + if (status != LIB$_NORMAL) + return 0; /* error, incl. time_diff < 0 (i.e. time-out) */ + + /* otherwise wait some more */ + } + } +} diff -ubBwrN ../../work/vim74/src/os_win32.c ./src/os_win32.c --- ../../work/vim74/src/os_win32.c 2013-08-10 13:39:12.000000000 +0300 +++ ./src/os_win32.c 2014-02-22 19:30:45.000000000 +0300 @@ -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 */ @@ -242,6 +232,94 @@ static char_u *exe_path = NULL; +static BOOL win8_or_later = FALSE; + +/* + * Version of ReadConsoleInput() that works with IME. + * Works around problems on Windows 8. + */ + static BOOL +read_console_input( + HANDLE hInput, + INPUT_RECORD *lpBuffer, + DWORD nLength, + LPDWORD lpEvents) +{ + enum + { + IRSIZE = 10 + }; + static INPUT_RECORD s_irCache[IRSIZE]; + static DWORD s_dwIndex = 0; + static DWORD s_dwMax = 0; + DWORD dwEvents; + int head; + int tail; + int i; + + if (!win8_or_later) + { + if (nLength == -1) + return PeekConsoleInput(hInput, lpBuffer, 1, lpEvents); + return ReadConsoleInput(hInput, lpBuffer, 1, &dwEvents); + } + + if (s_dwMax == 0) + { + if (nLength == -1) + return PeekConsoleInput(hInput, lpBuffer, 1, lpEvents); + if (!ReadConsoleInput(hInput, s_irCache, IRSIZE, &dwEvents)) + return FALSE; + s_dwIndex = 0; + s_dwMax = dwEvents; + if (dwEvents == 0) + { + *lpEvents = 0; + return TRUE; + } + + if (s_dwMax > 1) + { + head = 0; + tail = s_dwMax - 1; + while (head != tail) + { + if (s_irCache[head].EventType == WINDOW_BUFFER_SIZE_EVENT + && s_irCache[head + 1].EventType + == WINDOW_BUFFER_SIZE_EVENT) + { + /* Remove duplicate event to avoid flicker. */ + for (i = head; i < tail; ++i) + s_irCache[i] = s_irCache[i + 1]; + --tail; + continue; + } + head++; + } + s_dwMax = tail + 1; + } + } + + *lpBuffer = s_irCache[s_dwIndex]; + if (nLength != -1 && ++s_dwIndex >= s_dwMax) + s_dwMax = 0; + *lpEvents = 1; + return TRUE; +} + +/* + * Version of PeekConsoleInput() that works with IME. + */ + static BOOL +peek_console_input( + HANDLE hInput, + INPUT_RECORD *lpBuffer, + DWORD nLength, + LPDWORD lpEvents) +{ + return read_console_input(hInput, lpBuffer, -1, lpEvents); +} + static void get_exe_name(void) { @@ -573,6 +651,10 @@ g_PlatformId = ovi.dwPlatformId; + if ((ovi.dwMajorVersion == 6 && ovi.dwMinorVersion >= 2) + || ovi.dwMajorVersion > 6) + win8_or_later = TRUE; + #ifdef HAVE_ACL /* * Load the ADVAPI runtime if we are on anything @@ -1127,7 +1209,7 @@ INPUT_RECORD ir; MOUSE_EVENT_RECORD* pmer2 = &ir.Event.MouseEvent; - PeekConsoleInput(g_hConIn, &ir, 1, &cRecords); + peek_console_input(g_hConIn, &ir, 1, &cRecords); if (cRecords == 0 || ir.EventType != MOUSE_EVENT || !(pmer2->dwButtonState & LEFT_RIGHT)) @@ -1136,7 +1218,7 @@ { if (pmer2->dwEventFlags != MOUSE_MOVED) { - ReadConsoleInput(g_hConIn, &ir, 1, &cRecords); + read_console_input(g_hConIn, &ir, 1, &cRecords); return decode_mouse_event(pmer2); } @@ -1144,10 +1226,10 @@ s_yOldMouse == pmer2->dwMousePosition.Y) { /* throw away spurious mouse move */ - ReadConsoleInput(g_hConIn, &ir, 1, &cRecords); + read_console_input(g_hConIn, &ir, 1, &cRecords); /* are there any more mouse events in queue? */ - PeekConsoleInput(g_hConIn, &ir, 1, &cRecords); + peek_console_input(g_hConIn, &ir, 1, &cRecords); if (cRecords==0 || ir.EventType != MOUSE_EVENT) break; @@ -1384,7 +1466,7 @@ } cRecords = 0; - PeekConsoleInput(g_hConIn, &ir, 1, &cRecords); + peek_console_input(g_hConIn, &ir, 1, &cRecords); #ifdef FEAT_MBYTE_IME if (State & CMDLINE && msg_row == Rows - 1) @@ -1415,7 +1497,7 @@ if (ir.Event.KeyEvent.uChar.UnicodeChar == 0 && ir.Event.KeyEvent.wVirtualKeyCode == 13) { - ReadConsoleInput(g_hConIn, &ir, 1, &cRecords); + read_console_input(g_hConIn, &ir, 1, &cRecords); continue; } #endif @@ -1424,7 +1506,7 @@ return TRUE; } - ReadConsoleInput(g_hConIn, &ir, 1, &cRecords); + read_console_input(g_hConIn, &ir, 1, &cRecords); if (ir.EventType == FOCUS_EVENT) handle_focus_event(ir); @@ -1494,7 +1576,7 @@ return 0; # endif #endif - if (ReadConsoleInput(g_hConIn, &ir, 1, &cRecords) == 0) + if (read_console_input(g_hConIn, &ir, 1, &cRecords) == 0) { if (did_create_conin) read_error_exit(); @@ -2500,9 +2582,125 @@ } +#ifdef FEAT_MBYTE +/* + * fname_casew(): Wide version of fname_case(). Set the case of the file name, + * if it already exists. When "len" is > 0, also expand short to long + * filenames. + * Return FAIL if wide functions are not available, OK otherwise. + * NOTE: much of this is identical to fname_case(), keep in sync! + */ + static int +fname_casew( + WCHAR *name, + int len) +{ + WCHAR szTrueName[_MAX_PATH + 2]; + WCHAR szTrueNameTemp[_MAX_PATH + 2]; + WCHAR *ptrue, *ptruePrev; + WCHAR *porig, *porigPrev; + int flen; + WIN32_FIND_DATAW fb; + HANDLE hFind = INVALID_HANDLE_VALUE; + int c; + int slen; + + flen = (int)wcslen(name); + if (flen > _MAX_PATH) + return OK; + + /* slash_adjust(name) not needed, already adjusted by fname_case(). */ + + /* Build the new name in szTrueName[] one component at a time. */ + porig = name; + ptrue = szTrueName; + + if (iswalpha(porig[0]) && porig[1] == L':') + { + /* copy leading drive letter */ + *ptrue++ = *porig++; + *ptrue++ = *porig++; + } + *ptrue = NUL; /* in case nothing follows */ + + while (*porig != NUL) + { + /* copy \ characters */ + while (*porig == psepc) + *ptrue++ = *porig++; + + ptruePrev = ptrue; + porigPrev = porig; + while (*porig != NUL && *porig != psepc) + { + *ptrue++ = *porig++; + } + *ptrue = NUL; + + /* To avoid a slow failure append "\*" when searching a directory, + * server or network share. */ + wcscpy(szTrueNameTemp, szTrueName); + slen = (int)wcslen(szTrueNameTemp); + if (*porig == psepc && slen + 2 < _MAX_PATH) + wcscpy(szTrueNameTemp + slen, L"\\*"); + + /* Skip "", "." and "..". */ + if (ptrue > ptruePrev + && (ptruePrev[0] != L'.' + || (ptruePrev[1] != NUL + && (ptruePrev[1] != L'.' || ptruePrev[2] != NUL))) + && (hFind = FindFirstFileW(szTrueNameTemp, &fb)) + != INVALID_HANDLE_VALUE) + { + c = *porig; + *porig = NUL; + + /* Only use the match when it's the same name (ignoring case) or + * expansion is allowed and there is a match with the short name + * and there is enough room. */ + if (_wcsicoll(porigPrev, fb.cFileName) == 0 + || (len > 0 + && (_wcsicoll(porigPrev, fb.cAlternateFileName) == 0 + && (int)(ptruePrev - szTrueName) + + (int)wcslen(fb.cFileName) < len))) + { + wcscpy(ptruePrev, fb.cFileName); + + /* Look for exact match and prefer it if found. Must be a + * long name, otherwise there would be only one match. */ + while (FindNextFileW(hFind, &fb)) + { + if (*fb.cAlternateFileName != NUL + && (wcscoll(porigPrev, fb.cFileName) == 0 + || (len > 0 + && (_wcsicoll(porigPrev, + fb.cAlternateFileName) == 0 + && (int)(ptruePrev - szTrueName) + + (int)wcslen(fb.cFileName) < len)))) + { + wcscpy(ptruePrev, fb.cFileName); + break; + } + } + } + FindClose(hFind); + *porig = c; + ptrue = ptruePrev + wcslen(ptruePrev); + } + else if (hFind == INVALID_HANDLE_VALUE + && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) + return FAIL; + } + + wcscpy(name, szTrueName); + return OK; +} +#endif + /* * fname_case(): Set the case of the file name, if it already exists. * When "len" is > 0, also expand short to long filenames. + * NOTE: much of this is identical to fname_casew(), keep in sync! */ void fname_case( @@ -2520,11 +2718,44 @@ int slen; flen = (int)STRLEN(name); - if (flen == 0 || flen > _MAX_PATH) + if (flen == 0) return; slash_adjust(name); +#ifdef FEAT_MBYTE + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { + WCHAR *p = enc_to_utf16(name, NULL); + + if (p != NULL) + { + char_u *q; + WCHAR buf[_MAX_PATH + 2]; + + wcscpy(buf, p); + vim_free(p); + + if (fname_casew(buf, (len > 0) ? _MAX_PATH : 0) == OK) + { + q = utf16_to_enc(buf, NULL); + if (q != NULL) + { + vim_strncpy(name, q, (len > 0) ? len - 1 : flen); + vim_free(q); + return; + } + } + } + /* Retry with non-wide function (for Windows 98). */ + } +#endif + + /* If 'enc' is utf-8, flen can be larger than _MAX_PATH. + * So we should check this after calling wide function. */ + if (flen > _MAX_PATH) + return; + /* Build the new name in szTrueName[] one component at a time. */ porig = name; ptrue = szTrueName; @@ -2534,8 +2765,8 @@ /* copy leading drive letter */ *ptrue++ = *porig++; *ptrue++ = *porig++; - *ptrue = NUL; /* in case nothing follows */ } + *ptrue = NUL; /* in case nothing follows */ while (*porig != NUL) { @@ -2629,6 +2860,28 @@ char szUserName[256 + 1]; /* UNLEN is 256 */ DWORD cch = sizeof szUserName; +#ifdef FEAT_MBYTE + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { + WCHAR wszUserName[256 + 1]; /* UNLEN is 256 */ + DWORD wcch = sizeof(wszUserName) / sizeof(WCHAR); + + if (GetUserNameW(wszUserName, &wcch)) + { + char_u *p = utf16_to_enc(wszUserName, NULL); + + if (p != NULL) + { + vim_strncpy(s, p, len - 1); + vim_free(p); + return OK; + } + } + else if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return FAIL; + /* Retry with non-wide function (for Windows 98). */ + } +#endif if (GetUserName(szUserName, &cch)) { vim_strncpy(s, szUserName, len - 1); @@ -2649,6 +2902,28 @@ { DWORD cch = len; +#ifdef FEAT_MBYTE + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { + WCHAR wszHostName[256 + 1]; + DWORD wcch = sizeof(wszHostName) / sizeof(WCHAR); + + if (GetComputerNameW(wszHostName, &wcch)) + { + char_u *p = utf16_to_enc(wszHostName, NULL); + + if (p != NULL) + { + vim_strncpy(s, p, len - 1); + vim_free(p); + return; + } + } + else if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return; + /* Retry with non-wide function (for Windows 98). */ + } +#endif if (!GetComputerName(s, &cch)) vim_strncpy(s, "PC (Win32 Vim)", len - 1); } @@ -2695,6 +2970,8 @@ return OK; } } + else if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + return FAIL; /* Retry with non-wide function (for Windows 98). */ } #endif @@ -2702,9 +2979,8 @@ } /* - * get file permissions for `name' - * -1 : error - * else mode_t + * Get file permissions for "name". + * Return mode_t or -1 for error. */ long mch_getperm(char_u *name) @@ -2713,7 +2989,7 @@ int n; n = mch_stat(name, &st); - return n == 0 ? (int)st.st_mode : -1; + return n == 0 ? (long)(unsigned short)st.st_mode : -1L; } @@ -2736,7 +3012,7 @@ { n = _wchmod(p, perm); vim_free(p); - if (n == -1 && GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) + if (n == -1 && g_PlatformId == VER_PLATFORM_WIN32_NT) return FAIL; /* Retry with non-wide function (for Windows 98). */ } @@ -2955,8 +3231,7 @@ * -1 : error * else FILE_ATTRIBUTE_* defined in winnt.h */ - static - int + static int win32_getattrs(char_u *name) { int attr; @@ -3107,6 +3382,9 @@ { HANDLE hFile; int type; +#ifdef FEAT_MBYTE + WCHAR *wn = NULL; +#endif /* We can't open a file with a name "\\.\con" or "\\.\prn" and trying to * read from it later will cause Vim to hang. Thus return NODE_WRITABLE @@ -3114,6 +3392,30 @@ if (STRNCMP(name, "\\\\.\\", 4) == 0) return NODE_WRITABLE; +#ifdef FEAT_MBYTE + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { + wn = enc_to_utf16(name, NULL); + if (wn != NULL) + { + hFile = CreateFileW(wn, /* file name */ + GENERIC_WRITE, /* access mode */ + 0, /* share mode */ + NULL, /* security descriptor */ + OPEN_EXISTING, /* creation disposition */ + 0, /* file attributes */ + NULL); /* handle to template file */ + if (hFile == INVALID_HANDLE_VALUE + && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) + { + /* Retry with non-wide function (for Windows 98). */ + vim_free(wn); + wn = NULL; + } + } + } + if (wn == NULL) +#endif hFile = CreateFile(name, /* file name */ GENERIC_WRITE, /* access mode */ 0, /* share mode */ @@ -3122,6 +3424,9 @@ 0, /* file attributes */ NULL); /* handle to template file */ +#ifdef FEAT_MBYTE + vim_free(wn); +#endif if (hFile == INVALID_HANDLE_VALUE) return NODE_NORMAL; @@ -3618,6 +3923,50 @@ } #endif /* FEAT_GUI_W32 */ + static BOOL +vim_create_process( + char *cmd, + BOOL inherit_handles, + DWORD flags, + STARTUPINFO *si, + PROCESS_INFORMATION *pi) +{ +# ifdef FEAT_MBYTE + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { + WCHAR *wcmd = enc_to_utf16(cmd, NULL); + + if (wcmd != NULL) + { + BOOL ret; + ret = CreateProcessW( + NULL, /* Executable name */ + wcmd, /* Command to execute */ + NULL, /* Process security attributes */ + NULL, /* Thread security attributes */ + inherit_handles, /* Inherit handles */ + flags, /* Creation flags */ + NULL, /* Environment */ + NULL, /* Current directory */ + (LPSTARTUPINFOW)si, /* Startup information */ + pi); /* Process information */ + vim_free(wcmd); + return ret; + } + } +#endif + return CreateProcess( + NULL, /* Executable name */ + cmd, /* Command to execute */ + NULL, /* Process security attributes */ + NULL, /* Thread security attributes */ + inherit_handles, /* Inherit handles */ + flags, /* Creation flags */ + NULL, /* Environment */ + NULL, /* Current directory */ + si, /* Startup information */ + pi); /* Process information */ +} #if defined(FEAT_GUI_W32) || defined(PROTO) @@ -3664,18 +4013,8 @@ cmd += 3; /* Now, run the command */ - CreateProcess(NULL, /* Executable name */ - cmd, /* Command to execute */ - NULL, /* Process security attributes */ - NULL, /* Thread security attributes */ - FALSE, /* Inherit handles */ - CREATE_DEFAULT_ERROR_MODE | /* Creation flags */ - CREATE_NEW_CONSOLE, - NULL, /* Environment */ - NULL, /* Current directory */ - &si, /* Startup information */ - &pi); /* Process information */ - + vim_create_process(cmd, FALSE, + CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE, &si, &pi); /* Wait for the command to terminate before continuing */ if (g_PlatformId != VER_PLATFORM_WIN32s) @@ -4007,22 +4346,11 @@ p = cmd; } - /* Now, run the command */ - CreateProcess(NULL, /* Executable name */ - p, /* Command to execute */ - NULL, /* Process security attributes */ - NULL, /* Thread security attributes */ - - // this command can be litigious, handle inheritance was - // deactivated for pending temp file, but, if we deactivate - // it, the pipes don't work for some reason. - TRUE, /* Inherit handles, first deactivated, - * but needed */ - CREATE_DEFAULT_ERROR_MODE, /* Creation flags */ - NULL, /* Environment */ - NULL, /* Current directory */ - &si, /* Startup information */ - &pi); /* Process information */ + /* Now, run the command. + * About "Inherit handles" being TRUE: this command can be litigious, + * handle inheritance was deactivated for pending temp file, but, if we + * deactivate it, the pipes don't work for some reason. */ + vim_create_process(p, TRUE, CREATE_DEFAULT_ERROR_MODE, &si, &pi); if (p != cmd) vim_free(p); @@ -4049,10 +4377,10 @@ { MSG msg; - if (PeekMessage(&msg, (HWND)NULL, 0, 0, PM_REMOVE)) + if (pPeekMessage(&msg, (HWND)NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); - DispatchMessage(&msg); + pDispatchMessage(&msg); } /* write pipe information in the window */ @@ -4240,7 +4568,25 @@ } #else +# ifdef FEAT_MBYTE + static int +mch_system(char *cmd, int options) +{ + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { + WCHAR *wcmd = enc_to_utf16(cmd, NULL); + if (wcmd != NULL) + { + int ret = _wsystem(wcmd); + vim_free(wcmd); + return ret; + } + } + return system(cmd); +} +# else # define mch_system(c, o) system(c) +# endif #endif @@ -4325,6 +4671,7 @@ DWORD flags = CREATE_NEW_CONSOLE; char_u *p; + ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.lpReserved = NULL; si.lpDesktop = NULL; @@ -4408,16 +4755,7 @@ * inherit our handles which causes unpleasant dangling swap * files if we exit before the spawned process */ - if (CreateProcess(NULL, // Executable name - newcmd, // Command to execute - NULL, // Process security attributes - NULL, // Thread security attributes - FALSE, // Inherit handles - flags, // Creation flags - NULL, // Environment - NULL, // Current directory - &si, // Startup information - &pi)) // Process information + if (vim_create_process(newcmd, FALSE, flags, &si, &pi)) x = 0; else { @@ -4430,9 +4768,9 @@ if (newcmd != cmdbase) vim_free(newcmd); - if (si.hStdInput != NULL) + if (si.dwFlags == STARTF_USESTDHANDLES && si.hStdInput != NULL) { - /* Close the handle to \\.\NUL */ + /* Close the handle to \\.\NUL created above. */ CloseHandle(si.hStdInput); } /* Close the handles to the subprocess, so that it goes away */ @@ -5716,7 +6054,7 @@ { f = _wopen(wn, flags, mode); vim_free(wn); - if (f >= 0) + if (f >= 0 || g_PlatformId == VER_PLATFORM_WIN32_NT) return f; /* Retry with non-wide function (for Windows 98). Can't use * GetLastError() here and it's unclear what errno gets set to if @@ -5767,7 +6105,7 @@ _set_fmode(oldMode); # endif - if (f != NULL) + if (f != NULL || g_PlatformId == VER_PLATFORM_WIN32_NT) return f; /* Retry with non-wide function (for Windows 98). Can't use * GetLastError() here and it's unclear what errno gets set to if @@ -6102,6 +6440,7 @@ while (i > 0) free(argv[--i]); free(argv); + argv = NULL; argc = 0; } } diff -ubBwrN ../../work/vim74/src/os_win32.h ./src/os_win32.h --- ../../work/vim74/src/os_win32.h 2013-07-21 18:53:13.000000000 +0300 +++ ./src/os_win32.h 2014-02-22 19:30:40.000000000 +0300 @@ -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 -ubBwrN ../../work/vim74/src/osdef.sh ./src/osdef.sh --- ../../work/vim74/src/osdef.sh 2010-05-15 14:04:08.000000000 +0300 +++ ./src/osdef.sh 2014-02-22 19:30:41.000000000 +0300 @@ -47,11 +47,7 @@ #endif EOF -# Mac uses precompiled headers, but we need real headers here. -case `uname` in - Darwin) $CC -I. -I$srcdir -E -no-cpp-precomp osdef0.c >osdef0.cc;; - *) $CC -I. -I$srcdir -E osdef0.c >osdef0.cc;; -esac +$CC -I. -I$srcdir -E osdef0.c >osdef0.cc # insert a space in front of each line, so that a function name at the # start of the line is matched with "[)*, ]\1[ (]" diff -ubBwrN ../../work/vim74/src/popupmnu.c ./src/popupmnu.c --- ../../work/vim74/src/popupmnu.c 2011-08-17 19:04:28.000000000 +0300 +++ ./src/popupmnu.c 2014-02-22 19:30:42.000000000 +0300 @@ -282,6 +282,10 @@ int round; int n; + /* Never display more than we have */ + if (pum_first > pum_size - pum_height) + pum_first = pum_size - pum_height; + if (pum_scrollbar) { thumb_heigth = pum_height * pum_height / pum_size; @@ -672,10 +676,6 @@ #endif } - /* Never display more than we have */ - if (pum_first > pum_size - pum_height) - pum_first = pum_size - pum_height; - if (!resized) pum_redraw(); diff -ubBwrN ../../work/vim74/src/proto/blowfish.pro ./src/proto/blowfish.pro --- ../../work/vim74/src/proto/blowfish.pro 2013-08-10 14:37:06.000000000 +0300 +++ ./src/proto/blowfish.pro 2014-02-22 19:30:45.000000000 +0300 @@ -1,6 +1,6 @@ /* blowfish.c */ void bf_key_init __ARGS((char_u *password, char_u *salt, int salt_len)); -void bf_ofb_init __ARGS((char_u *iv, int iv_len)); +void bf_cfb_init __ARGS((char_u *iv, int iv_len)); void bf_crypt_encode __ARGS((char_u *from, size_t len, char_u *to)); void bf_crypt_decode __ARGS((char_u *ptr, long len)); void bf_crypt_init_keys __ARGS((char_u *passwd)); diff -ubBwrN ../../work/vim74/src/proto/eval.pro ./src/proto/eval.pro --- ../../work/vim74/src/proto/eval.pro 2013-08-10 14:37:09.000000000 +0300 +++ ./src/proto/eval.pro 2014-02-22 19:30:45.000000000 +0300 @@ -60,6 +60,7 @@ int list_append_string __ARGS((list_T *l, char_u *str, int len)); int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); +void list_insert __ARGS((list_T *l, listitem_T *ni, listitem_T *item)); int garbage_collect __ARGS((void)); void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); void set_ref_in_list __ARGS((list_T *l, int copyID)); diff -ubBwrN ../../work/vim74/src/proto/ex_cmds2.pro ./src/proto/ex_cmds2.pro --- ../../work/vim74/src/proto/ex_cmds2.pro 2013-08-10 14:37:10.000000000 +0300 +++ ./src/proto/ex_cmds2.pro 2014-02-22 19:30:42.000000000 +0300 @@ -35,7 +35,7 @@ int prof_def_func __ARGS((void)); int autowrite __ARGS((buf_T *buf, int forceit)); void autowrite_all __ARGS((void)); -int check_changed __ARGS((buf_T *buf, int checkaw, int mult_win, int forceit, int allbuf)); +int check_changed __ARGS((buf_T *buf, int flags)); void browse_save_fname __ARGS((buf_T *buf)); void dialog_changed __ARGS((buf_T *buf, int checkall)); int can_abandon __ARGS((buf_T *buf, int forceit)); diff -ubBwrN ../../work/vim74/src/proto/ex_eval.pro ./src/proto/ex_eval.pro --- ../../work/vim74/src/proto/ex_eval.pro 2013-08-10 14:37:10.000000000 +0300 +++ ./src/proto/ex_eval.pro 2014-02-22 19:30:43.000000000 +0300 @@ -4,8 +4,10 @@ int should_abort __ARGS((int retcode)); int aborted_in_try __ARGS((void)); int cause_errthrow __ARGS((char_u *mesg, int severe, int *ignore)); +void free_global_msglist __ARGS((void)); void do_errthrow __ARGS((struct condstack *cstack, char_u *cmdname)); int do_intthrow __ARGS((struct condstack *cstack)); +char_u *get_exception_string __ARGS((void *value, int type, char_u *cmdname, int *should_free)); void discard_current_exception __ARGS((void)); void report_make_pending __ARGS((int pending, void *value)); void report_resume_pending __ARGS((int pending, void *value)); diff -ubBwrN ../../work/vim74/src/proto/getchar.pro ./src/proto/getchar.pro --- ../../work/vim74/src/proto/getchar.pro 2013-08-10 14:37:12.000000000 +0300 +++ ./src/proto/getchar.pro 2014-02-22 19:30:45.000000000 +0300 @@ -1,8 +1,9 @@ /* getchar.c */ -void free_buff __ARGS((struct buffheader *buf)); +void free_buff __ARGS((buffheader_T *buf)); char_u *get_recorded __ARGS((void)); char_u *get_inserted __ARGS((void)); int stuff_empty __ARGS((void)); +int readbuf1_empty __ARGS((void)); void typeahead_noflush __ARGS((int c)); void flush_buffers __ARGS((int flush_typeahead)); void ResetRedobuff __ARGS((void)); diff -ubBwrN ../../work/vim74/src/proto/misc1.pro ./src/proto/misc1.pro --- ../../work/vim74/src/proto/misc1.pro 2013-08-10 14:37:20.000000000 +0300 +++ ./src/proto/misc1.pro 2014-02-22 19:30:42.000000000 +0300 @@ -69,6 +69,7 @@ char_u *getnextcomp __ARGS((char_u *fname)); char_u *get_past_head __ARGS((char_u *path)); int vim_ispathsep __ARGS((int c)); +int vim_ispathsep_nocolon __ARGS((int c)); int vim_ispathlistsep __ARGS((int c)); void shorten_dir __ARGS((char_u *str)); int dir_of_file_exists __ARGS((char_u *fname)); @@ -80,9 +81,10 @@ char_u *FullName_save __ARGS((char_u *fname, int force)); pos_T *find_start_comment __ARGS((int ind_maxcomment)); void do_c_expr_indent __ARGS((void)); -int cin_islabel __ARGS((int ind_maxcomment)); +int cin_islabel __ARGS((void)); int cin_iscase __ARGS((char_u *s, int strict)); int cin_isscopedecl __ARGS((char_u *s)); +void parse_cino __ARGS((buf_T *buf)); int get_c_indent __ARGS((void)); int get_expr_indent __ARGS((void)); int get_lisp_indent __ARGS((void)); diff -ubBwrN ../../work/vim74/src/proto/option.pro ./src/proto/option.pro --- ../../work/vim74/src/proto/option.pro 2013-08-10 14:37:22.000000000 +0300 +++ ./src/proto/option.pro 2014-02-22 19:30:45.000000000 +0300 @@ -23,6 +23,7 @@ char_u *check_stl_option __ARGS((char_u *s)); int get_option_value __ARGS((char_u *name, long *numval, char_u **stringval, int opt_flags)); int get_option_value_strict __ARGS((char_u *name, long *numval, char_u **stringval, int opt_type, void *from)); +char_u *option_iter_next __ARGS((void **option, int opt_type)); char_u *set_option_value __ARGS((char_u *name, long number, char_u *string, int opt_flags)); char_u *get_term_code __ARGS((char_u *tname)); char_u *get_highlight_default __ARGS((void)); @@ -59,7 +60,7 @@ void save_file_ff __ARGS((buf_T *buf)); int file_ff_differs __ARGS((buf_T *buf, int ignore_empty)); int check_ff_value __ARGS((char_u *p)); -long get_sw_value __ARGS((void)); +long get_sw_value __ARGS((buf_T *buf)); long get_sts_value __ARGS((void)); void find_mps_values __ARGS((int *initc, int *findc, int *backwards, int switchit)); /* vim: set ft=c : */ diff -ubBwrN ../../work/vim74/src/proto/spell.pro ./src/proto/spell.pro --- ../../work/vim74/src/proto/spell.pro 2013-08-10 14:37:26.000000000 +0300 +++ ./src/proto/spell.pro 2014-02-22 19:30:43.000000000 +0300 @@ -3,6 +3,7 @@ int spell_move_to __ARGS((win_T *wp, int dir, int allwords, int curline, hlf_T *attrp)); void spell_cat_line __ARGS((char_u *buf, char_u *line, int maxlen)); char_u *did_set_spelllang __ARGS((win_T *wp)); +void spell_delete_wordlist __ARGS((void)); void spell_free_all __ARGS((void)); void spell_reload __ARGS((void)); int spell_check_msm __ARGS((void)); diff -ubBwrN ../../work/vim74/src/proto/term.pro ./src/proto/term.pro --- ../../work/vim74/src/proto/term.pro 2013-08-10 14:37:28.000000000 +0300 +++ ./src/proto/term.pro 2014-02-22 19:30:41.000000000 +0300 @@ -35,7 +35,7 @@ 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 -ubBwrN ../../work/vim74/src/proto/window.pro ./src/proto/window.pro --- ../../work/vim74/src/proto/window.pro 2013-08-10 14:37:30.000000000 +0300 +++ ./src/proto/window.pro 2014-02-22 19:30:39.000000000 +0300 @@ -9,7 +9,7 @@ void win_equal __ARGS((win_T *next_curwin, int current, int dir)); void close_windows __ARGS((buf_T *buf, int keep_curwin)); int one_window __ARGS((void)); -void win_close __ARGS((win_T *win, int free_buf)); +int win_close __ARGS((win_T *win, int free_buf)); void win_close_othertab __ARGS((win_T *win, int free_buf, tabpage_T *tp)); void win_free_all __ARGS((void)); win_T *winframe_remove __ARGS((win_T *win, int *dirp, tabpage_T *tp)); diff -ubBwrN ../../work/vim74/src/regexp.c ./src/regexp.c --- ../../work/vim74/src/regexp.c 2013-08-01 19:31:30.000000000 +0300 +++ ./src/regexp.c 2014-02-22 19:30:43.000000000 +0300 @@ -4311,8 +4311,8 @@ */ for (;;) { - /* Some patterns may cause a long time to match, even though they are not - * illegal. E.g., "\([a-z]\+\)\+Q". Allow breaking them with CTRL-C. */ + /* Some patterns may take a long time to match, e.g., "\([a-z]\+\)\+Q". + * Allow interrupting them with CTRL-C. */ fast_breakcheck(); #ifdef DEBUG @@ -6455,7 +6455,8 @@ /* * Check whether a backreference matches. * Returns RA_FAIL, RA_NOMATCH or RA_MATCH. - * If "bytelen" is not NULL, it is set to the bytelength of the whole match. + * If "bytelen" is not NULL, it is set to the byte length of the match in the + * last line. */ static int match_with_backref(start_lnum, start_col, end_lnum, end_col, bytelen) @@ -6511,6 +6512,8 @@ /* Advance to next line. */ reg_nextline(); + if (bytelen != NULL) + *bytelen = 0; ++clnum; ccol = 0; if (got_int) @@ -8016,12 +8019,11 @@ } #endif /* - * If NFA engine failed, then revert to the backtracking engine. - * Except when there was a syntax error, which was properly handled by - * NFA engine. - */ + * If the NFA engine failed, the backtracking engine won't work either. + * if (regexp_engine == AUTOMATIC_ENGINE) prog = bt_regengine.regcomp(expr, re_flags); + */ } return prog; diff -ubBwrN ../../work/vim74/src/regexp_nfa.c ./src/regexp_nfa.c --- ../../work/vim74/src/regexp_nfa.c 2013-08-01 19:27:51.000000000 +0300 +++ ./src/regexp_nfa.c 2014-02-22 19:30:43.000000000 +0300 @@ -29,11 +29,14 @@ # define NFA_REGEXP_DEBUG_LOG "nfa_regexp_debug.log" #endif +/* Added to NFA_ANY - NFA_NUPPER_IC to include a NL. */ +#define NFA_ADD_NL 31 + 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 */ @@ -183,6 +186,13 @@ NFA_NLOWER, /* Match non-lowercase char */ NFA_UPPER, /* Match uppercase char */ NFA_NUPPER, /* Match non-uppercase char */ + NFA_LOWER_IC, /* Match [a-z] */ + NFA_NLOWER_IC, /* Match [^a-z] */ + NFA_UPPER_IC, /* Match [A-Z] */ + NFA_NUPPER_IC, /* Match [^A-Z] */ + + NFA_FIRST_NL = NFA_ANY + NFA_ADD_NL, + NFA_LAST_NL = NFA_NUPPER_IC + NFA_ADD_NL, NFA_CURSOR, /* Match cursor pos */ NFA_LNUM, /* Match line number */ @@ -199,9 +209,6 @@ NFA_MARK_LT, /* Match < mark */ NFA_VISUAL, /* Match Visual area */ - NFA_FIRST_NL = NFA_ANY + ADD_NL, - NFA_LAST_NL = NFA_NUPPER + ADD_NL, - /* Character classes [:alnum:] etc */ NFA_CLASS_ALNUM, NFA_CLASS_ALPHA, @@ -232,7 +239,9 @@ NFA_UPPER, NFA_NUPPER }; +static char_u e_nul_found[] = N_("E865: (NFA) Regexp end encountered prematurely"); static char_u e_misplaced[] = N_("E866: (NFA regexp) Misplaced %c"); +static char_u e_ill_char_class[] = N_("E877: (NFA regexp) Invalid character class: %ld"); /* NFA regexp \ze operator encountered. */ static int nfa_has_zend; @@ -578,6 +587,8 @@ * On failure, return 0 (=FAIL) * Start points to the first char of the range, while end should point * to the closing brace. + * Keep in mind that 'ignorecase' applies at execution time, thus [a-z] may + * need to be interpreted as [a-zA-Z]. */ static int nfa_recognize_char_class(start, end, extra_newl) @@ -681,7 +692,7 @@ return FAIL; if (newl == TRUE) - extra_newl = ADD_NL; + extra_newl = NFA_ADD_NL; switch (config) { @@ -710,13 +721,13 @@ case CLASS_not | CLASS_az | CLASS_AZ: return extra_newl + NFA_NALPHA; case CLASS_az: - return extra_newl + NFA_LOWER; + return extra_newl + NFA_LOWER_IC; case CLASS_not | CLASS_az: - return extra_newl + NFA_NLOWER; + return extra_newl + NFA_NLOWER_IC; case CLASS_AZ: - return extra_newl + NFA_UPPER; + return extra_newl + NFA_UPPER_IC; case CLASS_not | CLASS_AZ: - return extra_newl + NFA_NUPPER; + return extra_newl + NFA_NUPPER_IC; } return FAIL; } @@ -734,6 +745,11 @@ int c; { #define EMIT2(c) EMIT(c); EMIT(NFA_CONCAT); +#ifdef FEAT_MBYTE +# define EMITMBC(c) EMIT(c); EMIT(NFA_CONCAT); +#else +# define EMITMBC(c) +#endif #ifdef FEAT_MBYTE if (enc_utf8 || STRCMP(p_enc, "latin1") == 0 @@ -744,92 +760,338 @@ { case 'A': case 0300: case 0301: case 0302: case 0303: case 0304: case 0305: - EMIT2('A'); EMIT2(0300); EMIT2(0301); - EMIT2(0302); EMIT2(0303); EMIT2(0304); - EMIT2(0305); + CASEMBC(0x100) CASEMBC(0x102) CASEMBC(0x104) CASEMBC(0x1cd) + CASEMBC(0x1de) CASEMBC(0x1e0) CASEMBC(0x1ea2) + EMIT2('A'); EMIT2(0300); EMIT2(0301); EMIT2(0302); + EMIT2(0303); EMIT2(0304); EMIT2(0305); + EMITMBC(0x100) EMITMBC(0x102) EMITMBC(0x104) + EMITMBC(0x1cd) EMITMBC(0x1de) EMITMBC(0x1e0) + EMITMBC(0x1ea2) + return OK; + + case 'B': CASEMBC(0x1e02) CASEMBC(0x1e06) + EMIT2('B'); EMITMBC(0x1e02) EMITMBC(0x1e06) return OK; case 'C': case 0307: - EMIT2('C'); EMIT2(0307); + CASEMBC(0x106) CASEMBC(0x108) CASEMBC(0x10a) CASEMBC(0x10c) + EMIT2('C'); EMIT2(0307); EMITMBC(0x106) EMITMBC(0x108) + EMITMBC(0x10a) EMITMBC(0x10c) + return OK; + + case 'D': CASEMBC(0x10e) CASEMBC(0x110) CASEMBC(0x1e0a) + CASEMBC(0x1e0e) CASEMBC(0x1e10) + EMIT2('D'); EMITMBC(0x10e) EMITMBC(0x110) EMITMBC(0x1e0a) + EMITMBC(0x1e0e) EMITMBC(0x1e10) return OK; case 'E': case 0310: case 0311: case 0312: case 0313: - EMIT2('E'); EMIT2(0310); EMIT2(0311); - EMIT2(0312); EMIT2(0313); + CASEMBC(0x112) CASEMBC(0x114) CASEMBC(0x116) CASEMBC(0x118) + CASEMBC(0x11a) CASEMBC(0x1eba) CASEMBC(0x1ebc) + EMIT2('E'); EMIT2(0310); EMIT2(0311); EMIT2(0312); + EMIT2(0313); + EMITMBC(0x112) EMITMBC(0x114) EMITMBC(0x116) + EMITMBC(0x118) EMITMBC(0x11a) EMITMBC(0x1eba) + EMITMBC(0x1ebc) + return OK; + + case 'F': CASEMBC(0x1e1e) + EMIT2('F'); EMITMBC(0x1e1e) + return OK; + + case 'G': CASEMBC(0x11c) CASEMBC(0x11e) CASEMBC(0x120) + CASEMBC(0x122) CASEMBC(0x1e4) CASEMBC(0x1e6) CASEMBC(0x1f4) + CASEMBC(0x1e20) + EMIT2('G'); EMITMBC(0x11c) EMITMBC(0x11e) EMITMBC(0x120) + EMITMBC(0x122) EMITMBC(0x1e4) EMITMBC(0x1e6) + EMITMBC(0x1f4) EMITMBC(0x1e20) + return OK; + + case 'H': CASEMBC(0x124) CASEMBC(0x126) CASEMBC(0x1e22) + CASEMBC(0x1e26) CASEMBC(0x1e28) + EMIT2('H'); EMITMBC(0x124) EMITMBC(0x126) EMITMBC(0x1e22) + EMITMBC(0x1e26) EMITMBC(0x1e28) return OK; case 'I': case 0314: case 0315: case 0316: case 0317: - EMIT2('I'); EMIT2(0314); EMIT2(0315); - EMIT2(0316); EMIT2(0317); + CASEMBC(0x128) CASEMBC(0x12a) CASEMBC(0x12c) CASEMBC(0x12e) + CASEMBC(0x130) CASEMBC(0x1cf) CASEMBC(0x1ec8) + EMIT2('I'); EMIT2(0314); EMIT2(0315); EMIT2(0316); + EMIT2(0317); EMITMBC(0x128) EMITMBC(0x12a) + EMITMBC(0x12c) EMITMBC(0x12e) EMITMBC(0x130) + EMITMBC(0x1cf) EMITMBC(0x1ec8) + return OK; + + case 'J': CASEMBC(0x134) + EMIT2('J'); EMITMBC(0x134) + return OK; + + case 'K': CASEMBC(0x136) CASEMBC(0x1e8) CASEMBC(0x1e30) + CASEMBC(0x1e34) + EMIT2('K'); EMITMBC(0x136) EMITMBC(0x1e8) EMITMBC(0x1e30) + EMITMBC(0x1e34) + return OK; + + case 'L': CASEMBC(0x139) CASEMBC(0x13b) CASEMBC(0x13d) + CASEMBC(0x13f) CASEMBC(0x141) CASEMBC(0x1e3a) + EMIT2('L'); EMITMBC(0x139) EMITMBC(0x13b) EMITMBC(0x13d) + EMITMBC(0x13f) EMITMBC(0x141) EMITMBC(0x1e3a) + return OK; + + case 'M': CASEMBC(0x1e3e) CASEMBC(0x1e40) + EMIT2('M'); EMITMBC(0x1e3e) EMITMBC(0x1e40) return OK; case 'N': case 0321: - EMIT2('N'); EMIT2(0321); + CASEMBC(0x143) CASEMBC(0x145) CASEMBC(0x147) CASEMBC(0x1e44) + CASEMBC(0x1e48) + EMIT2('N'); EMIT2(0321); EMITMBC(0x143) EMITMBC(0x145) + EMITMBC(0x147) EMITMBC(0x1e44) EMITMBC(0x1e48) return OK; case 'O': case 0322: case 0323: case 0324: case 0325: - case 0326: - EMIT2('O'); EMIT2(0322); EMIT2(0323); - EMIT2(0324); EMIT2(0325); EMIT2(0326); + case 0326: case 0330: + CASEMBC(0x14c) CASEMBC(0x14e) CASEMBC(0x150) CASEMBC(0x1a0) + CASEMBC(0x1d1) CASEMBC(0x1ea) CASEMBC(0x1ec) CASEMBC(0x1ece) + EMIT2('O'); EMIT2(0322); EMIT2(0323); EMIT2(0324); + EMIT2(0325); EMIT2(0326); EMIT2(0330); + EMITMBC(0x14c) EMITMBC(0x14e) EMITMBC(0x150) + EMITMBC(0x1a0) EMITMBC(0x1d1) EMITMBC(0x1ea) + EMITMBC(0x1ec) EMITMBC(0x1ece) + return OK; + + case 'P': case 0x1e54: case 0x1e56: + EMIT2('P'); EMITMBC(0x1e54) EMITMBC(0x1e56) + return OK; + + case 'R': CASEMBC(0x154) CASEMBC(0x156) CASEMBC(0x158) + CASEMBC(0x1e58) CASEMBC(0x1e5e) + EMIT2('R'); EMITMBC(0x154) EMITMBC(0x156) EMITMBC(0x158) + EMITMBC(0x1e58) EMITMBC(0x1e5e) + return OK; + + case 'S': CASEMBC(0x15a) CASEMBC(0x15c) CASEMBC(0x15e) + CASEMBC(0x160) CASEMBC(0x1e60) + EMIT2('S'); EMITMBC(0x15a) EMITMBC(0x15c) EMITMBC(0x15e) + EMITMBC(0x160) EMITMBC(0x1e60) + return OK; + + case 'T': CASEMBC(0x162) CASEMBC(0x164) CASEMBC(0x166) + CASEMBC(0x1e6a) CASEMBC(0x1e6e) + EMIT2('T'); EMITMBC(0x162) EMITMBC(0x164) EMITMBC(0x166) + EMITMBC(0x1e6a) EMITMBC(0x1e6e) return OK; case 'U': case 0331: case 0332: case 0333: case 0334: - EMIT2('U'); EMIT2(0331); EMIT2(0332); - EMIT2(0333); EMIT2(0334); + CASEMBC(0x168) CASEMBC(0x16a) CASEMBC(0x16c) CASEMBC(0x16e) + CASEMBC(0x170) CASEMBC(0x172) CASEMBC(0x1af) CASEMBC(0x1d3) + CASEMBC(0x1ee6) + EMIT2('U'); EMIT2(0331); EMIT2(0332); EMIT2(0333); + EMIT2(0334); EMITMBC(0x168) EMITMBC(0x16a) + EMITMBC(0x16c) EMITMBC(0x16e) EMITMBC(0x170) + EMITMBC(0x172) EMITMBC(0x1af) EMITMBC(0x1d3) + EMITMBC(0x1ee6) + return OK; + + case 'V': CASEMBC(0x1e7c) + EMIT2('V'); EMITMBC(0x1e7c) + return OK; + + case 'W': CASEMBC(0x174) CASEMBC(0x1e80) CASEMBC(0x1e82) + CASEMBC(0x1e84) CASEMBC(0x1e86) + EMIT2('W'); EMITMBC(0x174) EMITMBC(0x1e80) EMITMBC(0x1e82) + EMITMBC(0x1e84) EMITMBC(0x1e86) + return OK; + + case 'X': CASEMBC(0x1e8a) CASEMBC(0x1e8c) + EMIT2('X'); EMITMBC(0x1e8a) EMITMBC(0x1e8c) return OK; case 'Y': case 0335: - EMIT2('Y'); EMIT2(0335); + CASEMBC(0x176) CASEMBC(0x178) CASEMBC(0x1e8e) CASEMBC(0x1ef2) + CASEMBC(0x1ef6) CASEMBC(0x1ef8) + EMIT2('Y'); EMIT2(0335); EMITMBC(0x176) EMITMBC(0x178) + EMITMBC(0x1e8e) EMITMBC(0x1ef2) EMITMBC(0x1ef6) + EMITMBC(0x1ef8) + return OK; + + case 'Z': CASEMBC(0x179) CASEMBC(0x17b) CASEMBC(0x17d) + CASEMBC(0x1b5) CASEMBC(0x1e90) CASEMBC(0x1e94) + EMIT2('Z'); EMITMBC(0x179) EMITMBC(0x17b) EMITMBC(0x17d) + EMITMBC(0x1b5) EMITMBC(0x1e90) EMITMBC(0x1e94) return OK; case 'a': case 0340: case 0341: case 0342: case 0343: case 0344: case 0345: - EMIT2('a'); EMIT2(0340); EMIT2(0341); - EMIT2(0342); EMIT2(0343); EMIT2(0344); - EMIT2(0345); + CASEMBC(0x101) CASEMBC(0x103) CASEMBC(0x105) CASEMBC(0x1ce) + CASEMBC(0x1df) CASEMBC(0x1e1) CASEMBC(0x1ea3) + EMIT2('a'); EMIT2(0340); EMIT2(0341); EMIT2(0342); + EMIT2(0343); EMIT2(0344); EMIT2(0345); + EMITMBC(0x101) EMITMBC(0x103) EMITMBC(0x105) + EMITMBC(0x1ce) EMITMBC(0x1df) EMITMBC(0x1e1) + EMITMBC(0x1ea3) + return OK; + + case 'b': CASEMBC(0x1e03) CASEMBC(0x1e07) + EMIT2('b'); EMITMBC(0x1e03) EMITMBC(0x1e07) return OK; case 'c': case 0347: - EMIT2('c'); EMIT2(0347); + CASEMBC(0x107) CASEMBC(0x109) CASEMBC(0x10b) CASEMBC(0x10d) + EMIT2('c'); EMIT2(0347); EMITMBC(0x107) EMITMBC(0x109) + EMITMBC(0x10b) EMITMBC(0x10d) + return OK; + + case 'd': CASEMBC(0x10f) CASEMBC(0x111) CASEMBC(0x1d0b) + CASEMBC(0x1e11) + EMIT2('d'); EMITMBC(0x10f) EMITMBC(0x111) EMITMBC(0x1e0b) + EMITMBC(0x01e0f) EMITMBC(0x1e11) return OK; case 'e': case 0350: case 0351: case 0352: case 0353: - EMIT2('e'); EMIT2(0350); EMIT2(0351); - EMIT2(0352); EMIT2(0353); + CASEMBC(0x113) CASEMBC(0x115) CASEMBC(0x117) CASEMBC(0x119) + CASEMBC(0x11b) CASEMBC(0x1ebb) CASEMBC(0x1ebd) + EMIT2('e'); EMIT2(0350); EMIT2(0351); EMIT2(0352); + EMIT2(0353); EMITMBC(0x113) EMITMBC(0x115) + EMITMBC(0x117) EMITMBC(0x119) EMITMBC(0x11b) + EMITMBC(0x1ebb) EMITMBC(0x1ebd) + return OK; + + case 'f': CASEMBC(0x1e1f) + EMIT2('f'); EMITMBC(0x1e1f) + return OK; + + case 'g': CASEMBC(0x11d) CASEMBC(0x11f) CASEMBC(0x121) + CASEMBC(0x123) CASEMBC(0x1e5) CASEMBC(0x1e7) CASEMBC(0x1f5) + CASEMBC(0x1e21) + EMIT2('g'); EMITMBC(0x11d) EMITMBC(0x11f) EMITMBC(0x121) + EMITMBC(0x123) EMITMBC(0x1e5) EMITMBC(0x1e7) + EMITMBC(0x1f5) EMITMBC(0x1e21) + return OK; + + case 'h': CASEMBC(0x125) CASEMBC(0x127) CASEMBC(0x1e23) + CASEMBC(0x1e27) CASEMBC(0x1e29) CASEMBC(0x1e96) + EMIT2('h'); EMITMBC(0x125) EMITMBC(0x127) EMITMBC(0x1e23) + EMITMBC(0x1e27) EMITMBC(0x1e29) EMITMBC(0x1e96) return OK; case 'i': case 0354: case 0355: case 0356: case 0357: - EMIT2('i'); EMIT2(0354); EMIT2(0355); - EMIT2(0356); EMIT2(0357); + CASEMBC(0x129) CASEMBC(0x12b) CASEMBC(0x12d) CASEMBC(0x12f) + CASEMBC(0x1d0) CASEMBC(0x1ec9) + EMIT2('i'); EMIT2(0354); EMIT2(0355); EMIT2(0356); + EMIT2(0357); EMITMBC(0x129) EMITMBC(0x12b) + EMITMBC(0x12d) EMITMBC(0x12f) EMITMBC(0x1d0) + EMITMBC(0x1ec9) + return OK; + + case 'j': CASEMBC(0x135) CASEMBC(0x1f0) + EMIT2('j'); EMITMBC(0x135) EMITMBC(0x1f0) + return OK; + + case 'k': CASEMBC(0x137) CASEMBC(0x1e9) CASEMBC(0x1e31) + CASEMBC(0x1e35) + EMIT2('k'); EMITMBC(0x137) EMITMBC(0x1e9) EMITMBC(0x1e31) + EMITMBC(0x1e35) + return OK; + + case 'l': CASEMBC(0x13a) CASEMBC(0x13c) CASEMBC(0x13e) + CASEMBC(0x140) CASEMBC(0x142) CASEMBC(0x1e3b) + EMIT2('l'); EMITMBC(0x13a) EMITMBC(0x13c) EMITMBC(0x13e) + EMITMBC(0x140) EMITMBC(0x142) EMITMBC(0x1e3b) + return OK; + + case 'm': CASEMBC(0x1e3f) CASEMBC(0x1e41) + EMIT2('m'); EMITMBC(0x1e3f) EMITMBC(0x1e41) return OK; case 'n': case 0361: - EMIT2('n'); EMIT2(0361); + CASEMBC(0x144) CASEMBC(0x146) CASEMBC(0x148) CASEMBC(0x149) + CASEMBC(0x1e45) CASEMBC(0x1e49) + EMIT2('n'); EMIT2(0361); EMITMBC(0x144) EMITMBC(0x146) + EMITMBC(0x148) EMITMBC(0x149) EMITMBC(0x1e45) + EMITMBC(0x1e49) return OK; case 'o': case 0362: case 0363: case 0364: case 0365: - case 0366: - EMIT2('o'); EMIT2(0362); EMIT2(0363); - EMIT2(0364); EMIT2(0365); EMIT2(0366); + case 0366: case 0370: + CASEMBC(0x14d) CASEMBC(0x14f) CASEMBC(0x151) CASEMBC(0x1a1) + CASEMBC(0x1d2) CASEMBC(0x1eb) CASEMBC(0x1ed) CASEMBC(0x1ecf) + EMIT2('o'); EMIT2(0362); EMIT2(0363); EMIT2(0364); + EMIT2(0365); EMIT2(0366); EMIT2(0370); + EMITMBC(0x14d) EMITMBC(0x14f) EMITMBC(0x151) + EMITMBC(0x1a1) EMITMBC(0x1d2) EMITMBC(0x1eb) + EMITMBC(0x1ed) EMITMBC(0x1ecf) + return OK; + + case 'p': CASEMBC(0x1e55) CASEMBC(0x1e57) + EMIT2('p'); EMITMBC(0x1e55) EMITMBC(0x1e57) + return OK; + + case 'r': CASEMBC(0x155) CASEMBC(0x157) CASEMBC(0x159) + CASEMBC(0x1e59) CASEMBC(0x1e5f) + EMIT2('r'); EMITMBC(0x155) EMITMBC(0x157) EMITMBC(0x159) + EMITMBC(0x1e59) EMITMBC(0x1e5f) + return OK; + + case 's': CASEMBC(0x15b) CASEMBC(0x15d) CASEMBC(0x15f) + CASEMBC(0x161) CASEMBC(0x1e61) + EMIT2('s'); EMITMBC(0x15b) EMITMBC(0x15d) EMITMBC(0x15f) + EMITMBC(0x161) EMITMBC(0x1e61) + return OK; + + case 't': CASEMBC(0x163) CASEMBC(0x165) CASEMBC(0x167) + CASEMBC(0x1e6b) CASEMBC(0x1e6f) CASEMBC(0x1e97) + EMIT2('t'); EMITMBC(0x163) EMITMBC(0x165) EMITMBC(0x167) + EMITMBC(0x1e6b) EMITMBC(0x1e6f) EMITMBC(0x1e97) return OK; case 'u': case 0371: case 0372: case 0373: case 0374: - EMIT2('u'); EMIT2(0371); EMIT2(0372); - EMIT2(0373); EMIT2(0374); + CASEMBC(0x169) CASEMBC(0x16b) CASEMBC(0x16d) CASEMBC(0x16f) + CASEMBC(0x171) CASEMBC(0x173) CASEMBC(0x1b0) CASEMBC(0x1d4) + CASEMBC(0x1ee7) + EMIT2('u'); EMIT2(0371); EMIT2(0372); EMIT2(0373); + EMIT2(0374); EMITMBC(0x169) EMITMBC(0x16b) + EMITMBC(0x16d) EMITMBC(0x16f) EMITMBC(0x171) + EMITMBC(0x173) EMITMBC(0x1b0) EMITMBC(0x1d4) + EMITMBC(0x1ee7) + return OK; + + case 'v': CASEMBC(0x1e7d) + EMIT2('v'); EMITMBC(0x1e7d) + return OK; + + case 'w': CASEMBC(0x175) CASEMBC(0x1e81) CASEMBC(0x1e83) + CASEMBC(0x1e85) CASEMBC(0x1e87) CASEMBC(0x1e98) + EMIT2('w'); EMITMBC(0x175) EMITMBC(0x1e81) EMITMBC(0x1e83) + EMITMBC(0x1e85) EMITMBC(0x1e87) EMITMBC(0x1e98) + return OK; + + case 'x': CASEMBC(0x1e8b) CASEMBC(0x1e8d) + EMIT2('x'); EMITMBC(0x1e8b) EMITMBC(0x1e8d) return OK; case 'y': case 0375: case 0377: - EMIT2('y'); EMIT2(0375); EMIT2(0377); + CASEMBC(0x177) CASEMBC(0x1e8f) CASEMBC(0x1e99) + CASEMBC(0x1ef3) CASEMBC(0x1ef7) CASEMBC(0x1ef9) + EMIT2('y'); EMIT2(0375); EMIT2(0377); EMITMBC(0x177) + EMITMBC(0x1e8f) EMITMBC(0x1e99) EMITMBC(0x1ef3) + EMITMBC(0x1ef7) EMITMBC(0x1ef9) return OK; - default: - return FAIL; + case 'z': CASEMBC(0x17a) CASEMBC(0x17c) CASEMBC(0x17e) + CASEMBC(0x1b6) CASEMBC(0x1e91) CASEMBC(0x1e95) + EMIT2('z'); EMITMBC(0x17a) EMITMBC(0x17c) EMITMBC(0x17e) + EMITMBC(0x1b6) EMITMBC(0x1e91) EMITMBC(0x1e95) + return OK; + + /* default: character itself */ } } - EMIT(c); + EMIT2(c); return OK; #undef EMIT2 +#undef EMITMBC } /* @@ -877,7 +1139,7 @@ switch (c) { case NUL: - EMSG_RET_FAIL(_("E865: (NFA) Regexp end encountered prematurely")); + EMSG_RET_FAIL(_(e_nul_found)); case Magic('^'): EMIT(NFA_BOL); @@ -900,6 +1162,9 @@ case Magic('_'): c = no_Magic(getchr()); + if (c == NUL) + EMSG_RET_FAIL(_(e_nul_found)); + if (c == '^') /* "\_^" is start-of-line */ { EMIT(NFA_BOL); @@ -914,7 +1179,7 @@ break; } - extra = ADD_NL; + extra = NFA_ADD_NL; /* "\_[" is collection plus newline */ if (c == '[') @@ -956,6 +1221,12 @@ p = vim_strchr(classchars, no_Magic(c)); if (p == NULL) { + if (extra == NFA_ADD_NL) + { + EMSGN(_(e_ill_char_class), c); + rc_did_emsg = TRUE; + return FAIL; + } EMSGN("INTERNAL: Unknown character class char: %ld", c); return FAIL; } @@ -970,7 +1241,7 @@ } #endif EMIT(nfa_classcodes[p - classchars]); - if (extra == ADD_NL) + if (extra == NFA_ADD_NL) { EMIT(NFA_NEWL); EMIT(NFA_OR); @@ -1123,8 +1394,9 @@ EMSG2_RET_FAIL( _("E678: Invalid character after %s%%[dxouU]"), reg_magic == MAGIC_ALL); + /* A NUL is stored in the text as NL */ /* TODO: what if a composing character follows? */ - EMIT(nr); + EMIT(nr == 0 ? 0x0a : nr); } break; @@ -1240,21 +1512,21 @@ { /* * Try to reverse engineer character classes. For example, - * recognize that [0-9] stands for \d and [A-Za-z_] with \h, + * recognize that [0-9] stands for \d and [A-Za-z_] for \h, * and perform the necessary substitutions in the NFA. */ result = nfa_recognize_char_class(regparse, endp, - extra == ADD_NL); + extra == NFA_ADD_NL); if (result != FAIL) { - if (result >= NFA_DIGIT && result <= NFA_NUPPER) - EMIT(result); - else /* must be char class + newline */ + if (result >= NFA_FIRST_NL && result <= NFA_LAST_NL) { - EMIT(result - ADD_NL); + EMIT(result - NFA_ADD_NL); EMIT(NFA_NEWL); EMIT(NFA_OR); } + else + EMIT(result); regparse = endp; mb_ptr_adv(regparse); return OK; @@ -1504,7 +1776,7 @@ * collection, add an OR below. But not for negated * range. */ if (!negated) - extra = ADD_NL; + extra = NFA_ADD_NL; } else { @@ -1537,7 +1809,7 @@ EMIT(NFA_END_COLL); /* \_[] also matches \n but it's not negated */ - if (extra == ADD_NL) + if (extra == NFA_ADD_NL) { EMIT(reg_string ? NL : NFA_NEWL); EMIT(NFA_OR); @@ -1744,8 +2016,8 @@ { /* 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; } @@ -1909,16 +2181,16 @@ 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; } @@ -2011,7 +2283,7 @@ if (c >= NFA_FIRST_NL && c <= NFA_LAST_NL) { addnl = TRUE; - c -= ADD_NL; + c -= NFA_ADD_NL; } STRCPY(code, ""); @@ -2162,7 +2434,7 @@ 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; @@ -2217,6 +2489,10 @@ case NFA_NLOWER:STRCPY(code, "NFA_NLOWER"); break; case NFA_UPPER: STRCPY(code, "NFA_UPPER"); break; case NFA_NUPPER:STRCPY(code, "NFA_NUPPER"); break; + case NFA_LOWER_IC: STRCPY(code, "NFA_LOWER_IC"); break; + case NFA_NLOWER_IC: STRCPY(code, "NFA_NLOWER_IC"); break; + case NFA_UPPER_IC: STRCPY(code, "NFA_UPPER_IC"); break; + case NFA_NUPPER_IC: STRCPY(code, "NFA_NUPPER_IC"); break; default: STRCPY(code, "CHAR(x)"); @@ -2687,6 +2963,10 @@ case NFA_NLOWER: case NFA_UPPER: case NFA_NUPPER: + case NFA_LOWER_IC: + case NFA_NLOWER_IC: + case NFA_UPPER_IC: + case NFA_NUPPER_IC: /* possibly non-ascii */ #ifdef FEAT_MBYTE if (has_mbyte) @@ -2798,7 +3078,7 @@ 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: @@ -2996,15 +3276,14 @@ 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))); @@ -3554,6 +3833,7 @@ 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)); @@ -3641,6 +3921,29 @@ } /* + * 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. */ static int @@ -3765,6 +4068,9 @@ if (two_unused) /* one is used and two is not: not equal */ return FALSE; + /* compare the state id */ + if (one->state->id != two->state->id) + return FALSE; /* compare the position */ if (REG_MULTI) return one->end.pos.lnum == two->end.pos.lnum @@ -3841,6 +4147,10 @@ case NFA_NLOWER: case NFA_UPPER: case NFA_NUPPER: + case NFA_LOWER_IC: + case NFA_NLOWER_IC: + case NFA_UPPER_IC: + case NFA_NUPPER_IC: case NFA_START_COLL: case NFA_START_NEG_COLL: case NFA_NEWL: @@ -3933,7 +4243,7 @@ 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; @@ -3979,7 +4289,7 @@ * endless loop for "\(\)*" */ default: - if (state->lastlist[nfa_ll_index] == l->id) + if (state->lastlist[nfa_ll_index] == l->id && state->c != NFA_SKIP) { /* This state is already in the list, don't add it again, * unless it is an MOPEN that is used for a backreference or @@ -4061,7 +4371,7 @@ 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); @@ -4096,7 +4406,7 @@ sub = &subs->norm; } #ifdef FEAT_SYN_HL - else if (state->c >= NFA_ZOPEN) + else if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9) { subidx = state->c - NFA_ZOPEN; sub = &subs->synt; @@ -4165,6 +4475,13 @@ } subs = addstate(l, state->out, subs, pim, off); + /* "subs" may have changed, need to set "sub" again */ +#ifdef FEAT_SYN_HL + if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9) + sub = &subs->synt; + else +#endif + sub = &subs->norm; if (save_in_use == -1) { @@ -4178,10 +4495,11 @@ 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; } @@ -4213,7 +4531,7 @@ sub = &subs->norm; } #ifdef FEAT_SYN_HL - else if (state->c >= NFA_ZCLOSE) + else if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9) { subidx = state->c - NFA_ZCLOSE; sub = &subs->synt; @@ -4257,6 +4575,13 @@ } subs = addstate(l, state->out, subs, pim, off); + /* "subs" may have changed, need to set "sub" again */ +#ifdef FEAT_SYN_HL + if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9) + sub = &subs->synt; + else +#endif + sub = &subs->norm; if (REG_MULTI) sub->list.multi[subidx].end = save_lpos; @@ -4419,7 +4744,7 @@ default: /* should not be here :P */ - EMSGN("E877: (NFA regexp) Invalid character class: %ld", class); + EMSGN(_(e_ill_char_class), class); return FAIL; } return FAIL; @@ -5018,6 +5343,7 @@ * 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 @@ -5051,6 +5377,12 @@ return FALSE; } #endif + /* Some patterns may take a long time to match, especially when using + * recursive_regmatch(). Allow interrupting them with CTRL-C. */ + fast_breakcheck(); + if (got_int) + return FALSE; + nfa_match = FALSE; /* Allocate memory for the lists of nodes. */ @@ -5278,7 +5610,10 @@ 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: @@ -5304,9 +5639,13 @@ { 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 @@ -5330,6 +5669,9 @@ 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 @@ -5413,6 +5755,13 @@ #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, @@ -5872,6 +6221,28 @@ ADD_STATE_IF_MATCH(t->state); break; + case NFA_LOWER_IC: /* [a-z] */ + result = ri_lower(curc) || (ireg_ic && ri_upper(curc)); + ADD_STATE_IF_MATCH(t->state); + break; + + case NFA_NLOWER_IC: /* [^a-z] */ + result = curc != NUL + && !(ri_lower(curc) || (ireg_ic && ri_upper(curc))); + ADD_STATE_IF_MATCH(t->state); + break; + + case NFA_UPPER_IC: /* [A-Z] */ + result = ri_upper(curc) || (ireg_ic && ri_lower(curc)); + ADD_STATE_IF_MATCH(t->state); + break; + + case NFA_NUPPER_IC: /* ^[A-Z] */ + result = curc != NUL + && !(ri_upper(curc) || (ireg_ic && ri_lower(curc))); + ADD_STATE_IF_MATCH(t->state); + break; + case NFA_BACKREF1: case NFA_BACKREF2: case NFA_BACKREF3: @@ -6098,6 +6469,7 @@ if (add_state != NULL) { nfa_pim_T *pim; + nfa_pim_T pim_copy; if (t->pim.result == NFA_PIM_UNUSED) pim = NULL; @@ -6171,6 +6543,15 @@ pim = NULL; } + /* If "pim" points into l->t it will become invalid when + * adding the state causes the list to be reallocated. Make a + * local copy to avoid that. */ + if (pim == &t->pim) + { + copy_pim(&pim_copy, pim); + pim = &pim_copy; + } + if (add_here) addstate_here(thislist, add_state, &t->subs, pim, &listidx); else diff -ubBwrN ../../work/vim74/src/screen.c ./src/screen.c --- ../../work/vim74/src/screen.c 2013-07-13 13:23:00.000000000 +0300 +++ ./src/screen.c 2014-02-22 19:30:44.000000000 +0300 @@ -6653,6 +6653,7 @@ win_T *wp; int draw_ruler; /* TRUE or FALSE */ { + static int entered = FALSE; int attr; int curattr; int row; @@ -6671,6 +6672,13 @@ win_T *ewp; int p_crb_save; + /* There is a tiny chance that this gets called recursively: When + * redrawing a status line triggers redrawing the ruler or tabline. + * Avoid trouble by not allowing recursion. */ + if (entered) + return; + entered = TRUE; + /* setup environment for the task at hand */ if (wp == NULL) { @@ -6746,7 +6754,7 @@ } if (maxwidth <= 0) - return; + goto theend; /* Temporarily reset 'cursorbind', we don't want a side effect from moving * the cursor away and back. */ @@ -6827,6 +6835,9 @@ while (col < Columns) TabPageIdxs[col++] = fillchar; } + +theend: + entered = FALSE; } #endif /* FEAT_STL_OPT */ @@ -7447,7 +7458,7 @@ { /* don't free regprog in the match list, it's a copy */ vim_regfree(shl->rm.regprog); - no_hlsearch = TRUE; + SET_NO_HLSEARCH(TRUE); } shl->rm.regprog = NULL; shl->lnum = 0; diff -ubBwrN ../../work/vim74/src/search.c ./src/search.c --- ../../work/vim74/src/search.c 2013-07-17 20:20:47.000000000 +0300 +++ ./src/search.c 2014-02-22 19:30:45.000000000 +0300 @@ -201,7 +201,7 @@ * Save the currently used pattern in the appropriate place, * unless the pattern should not be remembered. */ - if (!(options & SEARCH_KEEP)) + if (!(options & SEARCH_KEEP) && !cmdmod.keeppatterns) { /* search or global command */ if (pat_save == RE_SEARCH || pat_save == RE_BOTH) @@ -289,7 +289,7 @@ /* If 'hlsearch' set and search pat changed: need redraw. */ if (p_hls) redraw_all_later(SOME_VALID); - no_hlsearch = FALSE; + SET_NO_HLSEARCH(FALSE); #endif } } @@ -333,7 +333,7 @@ spats[1] = saved_spats[1]; last_idx = saved_last_idx; # ifdef FEAT_SEARCH_EXTRA - no_hlsearch = saved_no_hlsearch; + SET_NO_HLSEARCH(saved_no_hlsearch); # endif } } @@ -1148,7 +1148,7 @@ if (no_hlsearch && !(options & SEARCH_KEEP)) { redraw_all_later(SOME_VALID); - no_hlsearch = FALSE; + SET_NO_HLSEARCH(FALSE); } #endif @@ -1437,7 +1437,7 @@ curwin->w_set_curswant = TRUE; end_do_search: - if (options & SEARCH_KEEP) + if ((options & SEARCH_KEEP) || cmdmod.keeppatterns) spats[0].off = old_off; vim_free(strcopy); @@ -1760,6 +1760,9 @@ #endif pos = curwin->w_cursor; +#ifdef FEAT_VIRTUALEDIT + pos.coladd = 0; +#endif linep = ml_get(pos.lnum); cpo_match = (vim_strchr(p_cpo, CPO_MATCH) != NULL); @@ -4541,7 +4544,10 @@ /* Is the pattern is zero-width? */ one_char = is_one_char(spats[last_idx].pat); if (one_char == -1) - return FAIL; /* invalid pattern */ + { + p_ws = old_p_ws; + return FAIL; /* pattern not found */ + } /* * The trick is to first search backwards and then search forward again, @@ -4589,7 +4595,7 @@ ml_get(curwin->w_buffer->b_ml.ml_line_count)); } } - + p_ws = old_p_ws; } start_pos = pos; @@ -4604,7 +4610,6 @@ if (!VIsual_active) VIsual = start_pos; - p_ws = old_p_ws; curwin->w_cursor = pos; VIsual_active = TRUE; VIsual_mode = 'v'; @@ -4677,7 +4682,7 @@ && 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) + if (!result && inc(&pos) >= 0 && pos.col == regmatch.endpos[0].col) result = TRUE; } @@ -5559,7 +5564,9 @@ spats[idx].off.off = off; #ifdef FEAT_SEARCH_EXTRA if (setlast) - no_hlsearch = !hlsearch_on; + { + SET_NO_HLSEARCH(!hlsearch_on); + } #endif } } diff -ubBwrN ../../work/vim74/src/spell.c ./src/spell.c --- ../../work/vim74/src/spell.c 2013-07-17 18:28:28.000000000 +0300 +++ ./src/spell.c 2014-02-22 19:30:43.000000000 +0300 @@ -754,9 +754,9 @@ static void clear_spell_chartab __ARGS((spelltab_T *sp)); static int set_spell_finish __ARGS((spelltab_T *new_st)); static int spell_iswordp __ARGS((char_u *p, win_T *wp)); -static int spell_iswordp_nmw __ARGS((char_u *p)); +static int spell_iswordp_nmw __ARGS((char_u *p, win_T *wp)); #ifdef FEAT_MBYTE -static int spell_mb_isword_class __ARGS((int cl)); +static int spell_mb_isword_class __ARGS((int cl, win_T *wp)); static int spell_iswordp_w __ARGS((int *p, win_T *wp)); #endif static int write_spell_prefcond __ARGS((FILE *fd, garray_T *gap)); @@ -1149,7 +1149,7 @@ /* 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)) + else if (!spell_iswordp_nmw(ptr, wp)) { if (capcol != NULL && wp->w_s->b_cap_prog != NULL) { @@ -1561,7 +1561,7 @@ * accept a no-caps word, even when the dictionary * word specifies ONECAP. */ mb_ptr_back(mip->mi_word, p); - if (spell_iswordp_nmw(p) + if (spell_iswordp_nmw(p, mip->mi_win) ? capflags == WF_ONECAP : (flags & WF_ONECAP) != 0 && capflags != WF_ONECAP) @@ -4234,7 +4234,11 @@ if (spl_copy == NULL) goto theend; - /* loop over comma separated language names. */ +#ifdef FEAT_MBYTE + wp->w_s->b_cjk = 0; +#endif + + /* Loop over comma separated language names. */ for (splp = spl_copy; *splp != NUL; ) { /* Get one language name. */ @@ -4242,6 +4246,14 @@ region = NULL; len = (int)STRLEN(lang); + if (STRCMP(lang, "cjk") == 0) + { +#ifdef FEAT_MBYTE + wp->w_s->b_cjk = 1; +#endif + 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. */ @@ -4601,7 +4613,7 @@ int past_second = FALSE; /* past second word char */ /* find first letter */ - for (p = word; !spell_iswordp_nmw(p); mb_ptr_adv(p)) + 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 */ #ifdef FEAT_MBYTE @@ -4617,7 +4629,7 @@ * But a word with an upper char only at start is a ONECAP. */ for ( ; end == NULL ? *p != NUL : p < end; mb_ptr_adv(p)) - if (spell_iswordp_nmw(p)) + if (spell_iswordp_nmw(p, curwin)) { c = PTR2CHAR(p); if (!SPELL_ISUPPER(c)) @@ -4689,6 +4701,24 @@ return flags; } +/* + * Delete the internal wordlist and its .spl file. + */ + void +spell_delete_wordlist() +{ + char_u fname[MAXPATHL]; + + if (int_wordlist != NULL) + { + mch_remove(int_wordlist); + int_wordlist_spl(fname); + mch_remove(fname); + vim_free(int_wordlist); + int_wordlist = NULL; + } +} + # if defined(FEAT_MBYTE) || defined(EXITFREE) || defined(PROTO) /* * Free all languages. @@ -4698,7 +4728,6 @@ { slang_T *slang; buf_T *buf; - char_u fname[MAXPATHL]; /* Go through all buffers and handle 'spelllang'. */ for (buf = firstbuf; buf != NULL; buf = buf->b_next) @@ -4711,15 +4740,7 @@ slang_free(slang); } - if (int_wordlist != NULL) - { - /* Delete the internal wordlist and its .spl file */ - mch_remove(int_wordlist); - int_wordlist_spl(fname); - mch_remove(fname); - vim_free(int_wordlist); - int_wordlist = NULL; - } + spell_delete_wordlist(); vim_free(repl_to); repl_to = NULL; @@ -9479,7 +9500,8 @@ 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 +9547,7 @@ 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); } } @@ -9906,7 +9928,7 @@ c = mb_ptr2char(s); if (c > 255) - return spell_mb_isword_class(mb_get_class(s)); + return spell_mb_isword_class(mb_get_class(s), wp); return spelltab.st_isw[c]; } #endif @@ -9919,8 +9941,9 @@ * Unlike spell_iswordp() this doesn't check for "midword" characters. */ static int -spell_iswordp_nmw(p) +spell_iswordp_nmw(p, wp) char_u *p; + win_T *wp; { #ifdef FEAT_MBYTE int c; @@ -9929,7 +9952,7 @@ { c = mb_ptr2char(p); if (c > 255) - return spell_mb_isword_class(mb_get_class(p)); + return spell_mb_isword_class(mb_get_class(p), wp); return spelltab.st_isw[c]; } #endif @@ -9941,11 +9964,16 @@ * Return TRUE if word class indicates a word character. * Only for characters above 255. * Unicode subscript and superscript are not considered word characters. + * See also dbcs_class() and utf_class() in mbyte.c. */ static int -spell_mb_isword_class(cl) +spell_mb_isword_class(cl, wp) 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; } @@ -9970,9 +9998,10 @@ if (*s > 255) { if (enc_utf8) - return spell_mb_isword_class(utf_class(*s)); + return spell_mb_isword_class(utf_class(*s), wp); if (enc_dbcs) - return dbcs_class((unsigned)*s >> 8, *s & 0xff) >= 2; + return spell_mb_isword_class( + dbcs_class((unsigned)*s >> 8, *s & 0xff), wp); return 0; } return spelltab.st_isw[*s]; @@ -10135,7 +10164,7 @@ } /* - * "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. @@ -10192,13 +10221,13 @@ line = ml_get_curline(); p = line + curwin->w_cursor.col; /* Backup to before start of word. */ - while (p > line && spell_iswordp_nmw(p)) + while (p > line && spell_iswordp_nmw(p, curwin)) mb_ptr_back(line, p); /* Forward to start of word. */ - while (*p != NUL && !spell_iswordp_nmw(p)) + while (*p != NUL && !spell_iswordp_nmw(p, curwin)) mb_ptr_adv(p); - if (!spell_iswordp_nmw(p)) /* No word found. */ + if (!spell_iswordp_nmw(p, curwin)) /* No word found. */ { beep_flush(); return; @@ -10435,7 +10464,7 @@ for (;;) { mb_ptr_back(line, p); - if (p == line || spell_iswordp_nmw(p)) + if (p == line || spell_iswordp_nmw(p, curwin)) break; if (vim_regexec(®match, p, 0) && regmatch.endp[0] == line + endcol) @@ -11644,7 +11673,7 @@ /* When appending a compound word after a word character don't * use Onecap. */ - if (p != NULL && spell_iswordp_nmw(p)) + if (p != NULL && spell_iswordp_nmw(p, curwin)) c &= ~WF_ONECAP; make_case_word(tword + sp->ts_splitoff, preword + sp->ts_prewordlen, c); @@ -11894,7 +11923,8 @@ * character when the word ends. But only when the * good word can end. */ if (((!try_compound && !spell_iswordp_nmw(fword - + sp->ts_fidx)) + + sp->ts_fidx, + curwin)) || fword_ends) && fword[sp->ts_fidx] != NUL && goodword_ends) @@ -13377,9 +13407,8 @@ /* Lookup the word "orgnr" one of the two tries. */ n = 0; - wlen = 0; wordcount = 0; - for (;;) + for (wlen = 0; wlen < MAXWLEN - 3; ++wlen) { i = 1; if (wordcount == orgnr && byts[n + 1] == NUL) @@ -13393,6 +13422,7 @@ if (i > byts[n]) /* safety check */ { STRCPY(theword + wlen, "BAD"); + wlen += 3; goto badword; } @@ -13405,7 +13435,7 @@ wordcount += wc; } - theword[wlen++] = byts[n + i]; + theword[wlen] = byts[n + i]; n = idxs[n + i]; } badword: @@ -14225,7 +14255,7 @@ } else { - if (spell_iswordp_nmw(s)) + if (spell_iswordp_nmw(s, curwin)) *t++ = *s; ++s; } @@ -14520,7 +14550,7 @@ else { did_white = FALSE; - if (!spell_iswordp_nmw(t)) + if (!spell_iswordp_nmw(t, curwin)) continue; } } @@ -15568,11 +15598,21 @@ 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; @@ -16034,7 +16074,7 @@ for (p = line + startcol; p > line; ) { mb_ptr_back(line, p); - if (spell_iswordp_nmw(p)) + if (spell_iswordp_nmw(p, curwin)) break; } diff -ubBwrN ../../work/vim74/src/structs.h ./src/structs.h --- ../../work/vim74/src/structs.h 2013-07-03 16:35:59.000000000 +0300 +++ ./src/structs.h 2014-02-22 19:30:45.000000000 +0300 @@ -471,12 +471,16 @@ blocknr_T nt_new_bnum; /* new, positive, number */ }; + +typedef struct buffblock buffblock_T; +typedef struct buffheader buffheader_T; + /* * structure used to store one block of the stuff/redo/recording buffers */ struct buffblock { - struct buffblock *b_next; /* pointer to next buffblock */ + buffblock_T *b_next; /* pointer to next buffblock */ char_u b_str[1]; /* contents (actually longer) */ }; @@ -485,8 +489,8 @@ */ struct buffheader { - struct buffblock bh_first; /* first (dummy) block of list */ - struct buffblock *bh_curr; /* buffblock for appending */ + buffblock_T bh_first; /* first (dummy) block of list */ + buffblock_T *bh_curr; /* buffblock for appending */ int bh_index; /* index for reading */ int bh_space; /* space in bh_curr for appending */ }; @@ -542,6 +546,7 @@ int keepmarks; /* TRUE when ":keepmarks" was used */ int keepjumps; /* TRUE when ":keepjumps" was used */ int lockmarks; /* TRUE when ":lockmarks" was used */ + int keeppatterns; /* TRUE when ":keeppatterns" was used */ # ifdef FEAT_AUTOCMD char_u *save_ei; /* saved value of 'eventignore' */ # endif @@ -963,7 +968,8 @@ int typebuf_valid; /* TRUE when save_typebuf valid */ int old_char; int old_mod_mask; - struct buffheader save_stuffbuff; + buffheader_T save_readbuf1; + buffheader_T save_readbuf2; #ifdef USE_INPUT_BUF char_u *save_inputbuf; #endif @@ -1309,6 +1315,9 @@ regprog_T *b_cap_prog; /* program for 'spellcapcheck' */ char_u *b_p_spf; /* 'spellfile' */ char_u *b_p_spl; /* 'spelllang' */ +# ifdef FEAT_MBYTE + int b_cjk; /* all CJK letters as OK */ +# endif #endif #if !defined(FEAT_SYN_HL) && !defined(FEAT_SPELL) int dummy; @@ -1627,12 +1636,52 @@ char_u *b_p_dict; /* 'dictionary' local value */ char_u *b_p_tsr; /* 'thesaurus' local value */ #endif + long b_p_ul; /* 'undolevels' local value */ #ifdef FEAT_PERSISTENT_UNDO int b_p_udf; /* 'undofile' */ #endif /* end of buffer options */ +#ifdef FEAT_CINDENT + /* values set from b_p_cino */ + int b_ind_level; + int b_ind_open_imag; + int b_ind_no_brace; + int b_ind_first_open; + int b_ind_open_extra; + int b_ind_close_extra; + int b_ind_open_left_imag; + int b_ind_jump_label; + int b_ind_case; + int b_ind_case_code; + int b_ind_case_break; + int b_ind_param; + int b_ind_func_type; + int b_ind_comment; + int b_ind_in_comment; + int b_ind_in_comment2; + int b_ind_cpp_baseclass; + int b_ind_continuation; + int b_ind_unclosed; + int b_ind_unclosed2; + int b_ind_unclosed_noignore; + int b_ind_unclosed_wrapped; + int b_ind_unclosed_whiteok; + int b_ind_matching_paren; + int b_ind_paren_prev; + int b_ind_maxparen; + int b_ind_maxcomment; + int b_ind_scopedecl; + int b_ind_scopedecl_code; + int b_ind_java; + int b_ind_js; + int b_ind_keep_case_label; + int b_ind_hash_comment; + int b_ind_cpp_namespace; + int b_ind_if_for_while; +#endif + linenr_T b_no_eol_lnum; /* non-zero lnum when last line of next binary * write should not have an end-of-line */ diff -ubBwrN ../../work/vim74/src/syntax.c ./src/syntax.c --- ../../work/vim74/src/syntax.c 2013-06-08 17:10:08.000000000 +0300 +++ ./src/syntax.c 2014-02-22 19:30:43.000000000 +0300 @@ -7071,7 +7071,7 @@ retval = source_runtime(buf, FALSE); vim_free(buf); #ifdef FEAT_AUTOCMD - apply_autocmds(EVENT_COLORSCHEME, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, FALSE, curbuf); #endif } recursive = FALSE; diff -ubBwrN ../../work/vim74/src/tag.c ./src/tag.c --- ../../work/vim74/src/tag.c 2013-06-15 23:26:26.000000000 +0300 +++ ./src/tag.c 2014-02-22 19:30:43.000000000 +0300 @@ -1326,6 +1326,7 @@ int match_no_ic = 0;/* matches with rm_ic == FALSE */ int match_re; /* match with regexp */ int matchoff = 0; + int save_emsg_off; #ifdef FEAT_EMACS_TAGS /* @@ -1442,7 +1443,10 @@ 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; @@ -1797,13 +1801,16 @@ */ 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 +1905,7 @@ #endif } +parse_line: /* * Figure out where the different strings are in this line. * For "normal" tags: Do a quick check if the tag matches. @@ -3326,7 +3334,9 @@ #ifdef FEAT_SEARCH_EXTRA /* restore no_hlsearch when keeping the old search pattern */ if (search_options) - no_hlsearch = save_no_hlsearch; + { + SET_NO_HLSEARCH(save_no_hlsearch); + } #endif /* Return OK if jumped to another file (at least we found the file!). */ diff -ubBwrN ../../work/vim74/src/term.c ./src/term.c --- ../../work/vim74/src/term.c 2013-07-04 23:29:28.000000000 +0300 +++ ./src/term.c 2014-02-22 19:30:41.000000000 +0300 @@ -3356,7 +3356,7 @@ * 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 -ubBwrN ../../work/vim74/src/testdir/Make_amiga.mak ./src/testdir/Make_amiga.mak --- ../../work/vim74/src/testdir/Make_amiga.mak 2013-07-09 14:40:02.000000000 +0300 +++ ./src/testdir/Make_amiga.mak 2014-02-22 19:30:45.000000000 +0300 @@ -33,7 +33,9 @@ test76.out test77.out test78.out test79.out test80.out \ test81.out test82.out test83.out test84.out test88.out \ test89.out test90.out test91.out test92.out test93.out \ - test94.out test95.out test96.out test97.out test98.out + test94.out test95.out test96.out test97.out test98.out \ + test99.out test100.out test101.out test102.out test103.out \ + test104.out .SUFFIXES: .in .out @@ -148,3 +150,9 @@ test96.out: test96.in test97.out: test97.in test98.out: test98.in +test99.out: test99.in +test100.out: test100.in +test101.out: test101.in +test102.out: test102.in +test103.out: test103.in +test104.out: test104.in diff -ubBwrN ../../work/vim74/src/testdir/Make_dos.mak ./src/testdir/Make_dos.mak --- ../../work/vim74/src/testdir/Make_dos.mak 2013-07-09 14:40:30.000000000 +0300 +++ ./src/testdir/Make_dos.mak 2014-02-22 19:30:45.000000000 +0300 @@ -32,7 +32,8 @@ test79.out test80.out test81.out test82.out test83.out \ test84.out test85.out test86.out test87.out test88.out \ test89.out test90.out test91.out test92.out test93.out \ - test94.out test95.out test96.out test98.out + test94.out test95.out test96.out test98.out test99.out \ + test100.out test101.out test102.out test103.out test104.out SCRIPTS32 = test50.out test70.out diff -ubBwrN ../../work/vim74/src/testdir/Make_ming.mak ./src/testdir/Make_ming.mak --- ../../work/vim74/src/testdir/Make_ming.mak 2013-07-09 14:40:38.000000000 +0300 +++ ./src/testdir/Make_ming.mak 2014-02-22 19:30:45.000000000 +0300 @@ -52,7 +52,8 @@ test79.out test80.out test81.out test82.out test83.out \ test84.out test85.out test86.out test87.out test88.out \ test89.out test90.out test91.out test92.out test93.out \ - test94.out test95.out test96.out test98.out + test94.out test95.out test96.out test98.out test99.out \ + test100.out test101.out test102.out test103.out test104.out SCRIPTS32 = test50.out test70.out diff -ubBwrN ../../work/vim74/src/testdir/Make_os2.mak ./src/testdir/Make_os2.mak --- ../../work/vim74/src/testdir/Make_os2.mak 2013-07-09 14:40:43.000000000 +0300 +++ ./src/testdir/Make_os2.mak 2014-02-22 19:30:45.000000000 +0300 @@ -34,7 +34,8 @@ test76.out test77.out test78.out test79.out test80.out \ test81.out test82.out test83.out test84.out test88.out \ test89.out test90.out test91.out test92.out test93.out \ - test94.out test95.out test96.out test98.out + test94.out test95.out test96.out test98.out test99.out \ + test100.out test101.out test102.out test103.out test104.out .SUFFIXES: .in .out diff -ubBwrN ../../work/vim74/src/testdir/Make_vms.mms ./src/testdir/Make_vms.mms --- ../../work/vim74/src/testdir/Make_vms.mms 2013-07-09 14:40:47.000000000 +0300 +++ ./src/testdir/Make_vms.mms 2014-02-22 19:30:45.000000000 +0300 @@ -4,7 +4,7 @@ # Authors: Zoltan Arpadffy, # Sandor Kopanyi, # -# Last change: 2013 Jul 09 +# Last change: 2013 Nov 21 # # This has been tested on VMS 6.2 to 8.3 on DEC Alpha, VAX and IA64. # Edit the lines in the Configuration section below to select. @@ -78,7 +78,8 @@ test77.out test78.out test79.out test80.out test81.out \ test82.out test83.out test84.out test88.out test89.out \ test90.out test91.out test92.out test93.out test94.out \ - test95.out test96.out test97.out test98.out + test95.out test96.out test97.out test98.out test99.out \ + test100.out test101.out test102.out test103.out test104.out # Known problems: # Test 30: a problem around mac format - unknown reason diff -ubBwrN ../../work/vim74/src/testdir/test1.in ./src/testdir/test1.in --- ../../work/vim74/src/testdir/test1.in 2012-04-05 17:37:37.000000000 +0300 +++ ./src/testdir/test1.in 2014-02-22 19:30:40.000000000 +0300 @@ -18,6 +18,10 @@ Similar logic is applied to the +lua feature, using lua.vim. STARTTEST +:" If columns or lines are too small, create wrongtermsize. +:" (Some tests will fail. When columns and/or lines are small) +:if &lines < 24 || &columns < 80 | sp another | w! wrongtermsize | qa! | endif +:" :" Write a single line to test.out to check if testing works at all. :%d athis is a test:w! test.out diff -ubBwrN ../../work/vim74/src/testdir/test14.in ./src/testdir/test14.in --- ../../work/vim74/src/testdir/test14.in 2013-04-03 21:59:14.000000000 +0300 +++ ./src/testdir/test14.in 2014-02-22 19:30:45.000000000 +0300 @@ -47,7 +47,19 @@ /two :call search('.', 'c') :call append(line('$'), getline('.')[col('.') - 1:]) -:/^search()/,$w >>test.out +:" +/^substitute +:s/foo/bar/ +:$put =@/ +/^substitute +:keeppatterns s/asdf/xyz/ +:$put =@/ +/^substitute +Y:$put =@0 +/bar /e +:$put =@0 +-:keeppatterns /xyz +0dn:/^search()/,$w >>test.out :qa! ENDTEST @@ -81,6 +93,7 @@ foobar +substitute foo asdf one two search() diff -ubBwrN ../../work/vim74/src/testdir/test14.ok ./src/testdir/test14.ok --- ../../work/vim74/src/testdir/test14.ok 2013-04-03 21:59:14.000000000 +0300 +++ ./src/testdir/test14.ok 2014-02-22 19:30:45.000000000 +0300 @@ -20,3 +20,7 @@ 1 1 two +foo +^substitute +substitute bar xyz +xyz diff -ubBwrN ../../work/vim74/src/testdir/test20.in ./src/testdir/test20.in --- ../../work/vim74/src/testdir/test20.in 2010-05-15 14:04:10.000000000 +0300 +++ ./src/testdir/test20.in 2014-02-22 19:30:40.000000000 +0300 @@ -9,11 +9,17 @@ @auY:quit! GP /start here$ -jjlld -:/here$/,$-1w! test.out +"by$jjlld +/456$ +jj"bP +:/56$/,$-1w! test.out :qa! ENDTEST +123456 +234567 +345678 + test text test tex start here some text test text diff -ubBwrN ../../work/vim74/src/testdir/test20.ok ./src/testdir/test20.ok --- ../../work/vim74/src/testdir/test20.ok 2010-05-15 14:04:10.000000000 +0300 +++ ./src/testdir/test20.ok 2014-02-22 19:30:40.000000000 +0300 @@ -1,3 +1,7 @@ +123start here56 +234start here67 +345start here78 + test text test tex rt here somext tesext diff -ubBwrN ../../work/vim74/src/testdir/test32.in ./src/testdir/test32.in --- ../../work/vim74/src/testdir/test32.in 2010-05-15 14:04:10.000000000 +0300 +++ ./src/testdir/test32.in 2014-02-22 19:30:40.000000000 +0300 @@ -36,6 +36,9 @@ :w Xtest11.one :w Xtest11.two OIXA +:" use CTRL-X CTRL-F to complete Xtest11.one, remove it and then use +:" CTRL-X CTRL-F again to verify this doesn't cause trouble. +OXddk :se cpt=w OST :se cpt=u nohid diff -ubBwrN ../../work/vim74/src/testdir/test34.in ./src/testdir/test34.in --- ../../work/vim74/src/testdir/test34.in 2012-07-16 17:51:29.000000000 +0300 +++ ./src/testdir/test34.in 2014-02-22 19:30:43.000000000 +0300 @@ -1,6 +1,7 @@ Test for user functions. Also test an mapping calling a function. Also test that a builtin function cannot be replaced. +Also test for regression when calling arbitrary expression. STARTTEST :so small.vim @@ -62,7 +63,17 @@ [(one again:call append(line('$'), max([1, 2, 3])) :call extend(g:, {'max': function('min')}) :call append(line('$'), max([1, 2, 3])) -:$-7,$w! test.out +:try +: " Regression: the first line below used to throw ?E110: Missing ')'? +: " Second is here just to prove that this line is correct when not skipping +: " rhs of &&. +: $put =(0&&(function('tr'))(1, 2, 3)) +: $put =(1&&(function('tr'))(1, 2, 3)) +:catch +: $put ='!!! Unexpected exception:' +: $put =v:exception +:endtry +:$-9,$w! test.out :delfunc Table :delfunc Compute :delfunc Expr1 diff -ubBwrN ../../work/vim74/src/testdir/test34.ok ./src/testdir/test34.ok --- ../../work/vim74/src/testdir/test34.ok 2012-07-16 17:43:15.000000000 +0300 +++ ./src/testdir/test34.ok 2014-02-22 19:30:43.000000000 +0300 @@ -6,3 +6,5 @@ 1. one again 3 3 +0 +1 diff -ubBwrN ../../work/vim74/src/testdir/test37.ok ./src/testdir/test37.ok --- ../../work/vim74/src/testdir/test37.ok 2010-05-15 14:04:10.000000000 +0300 +++ ./src/testdir/test37.ok 2014-02-22 19:30:44.000000000 +0300 @@ -27,7 +27,7 @@ . line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16 :set scrollbind -zt: -. line 15 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 15 :set scrollbind -. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11 +. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16 +j: +. line 12 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 12 diff -ubBwrN ../../work/vim74/src/testdir/test39.in ./src/testdir/test39.in --- ../../work/vim74/src/testdir/test39.in 2013-03-07 20:30:38.000000000 +0300 +++ ./src/testdir/test39.in 2014-02-22 19:30:44.000000000 +0300 @@ -19,6 +19,22 @@ :" Test block-change G$khhhhhkkcmno :$-4,$w! test.out +:" Test block-insert using cursor keys for movement +/^aaaa/ +:exe ":norm! l\jjjlllI\\ \" +:/^aa/,/^$/w >> test.out +:" Test for Visual block was created with the last $ +/^A23$/ +:exe ":norm! l\j$Aab\" +:.,/^$/w >> test.out +:" Test for Visual block was created with the middle $ (1) +/^B23$/ +:exe ":norm! l\j$hAab\" +:.,/^$/w >> test.out +:" Test for Visual block was created with the middle $ (2) +/^C23$/ +:exe ":norm! l\j$hhAab\" +:.,/^$/w >> test.out :" gUe must uppercase a whole word, also when changes to SS Gothe youtueuu endYpk0wgUe :" gUfx must uppercase until x, inclusive. @@ -32,10 +48,34 @@ doh dutVkUj :" Uppercase part of two lines ddppi333k0i222fyllvjfuUk +:" visual replace using Enter or NL +G3o1234567892k05l2jr G3o987652k02l2jr +G3o1234567892k05l2jr +G3o987652k02l2jr +:" +:" Test cursor position. When ve=block and Visual block mode and $gj +:set ve=block +:exe ":norm! 2k\$gj\" +:let cpos=getpos("'>") +:$put ='col:'.cpos[2].' off:'.cpos[3] :/^the/,$w >> test.out :qa! ENDTEST +aaaaaa +bbbbbb +cccccc +dddddd + +A23 +4567 + +B23 +4567 + +C23 +4567 + abcdefghijklm abcdefghijklm abcdefghijklm diff -ubBwrN ../../work/vim74/src/testdir/test39.ok ./src/testdir/test39.ok --- ../../work/vim74/src/testdir/test39.ok 2013-03-07 20:28:51.000000000 +0300 +++ ./src/testdir/test39.ok 2014-02-22 19:30:43.000000000 +0300 @@ -3,6 +3,20 @@ axyzqqqqef mno ghijklm axyzqqqqefgmnoklm abcdqqqqijklm +aaa aaa +bbb bbb +ccc ccc +ddd ddd + +A23ab +4567ab + +B23 ab +4567ab + +C23ab +456ab7 + the YOUTUSSEUU end - yOUSSTUSSEXu - THE YOUTUSSEUU END diff -ubBwrN ../../work/vim74/src/testdir/test44.in ./src/testdir/test44.in --- ../../work/vim74/src/testdir/test44.in 2013-05-26 15:16:31.000000000 +0300 +++ ./src/testdir/test44.in 2014-02-22 19:30:40.000000000 +0300 @@ -1,9 +1,11 @@ Tests for regexp with multi-byte encoding and various magic settings. Test matchstr() with a count and multi-byte chars. +See test99 for exactly the same test with re=2. STARTTEST :so mbyte.vim :set nocompatible encoding=utf-8 termencoding=latin1 viminfo+=nviminfo +:set re=1 /^1 /a*b\{2}c\+/e x/\Md\*e\{2}f\+/e diff -ubBwrN ../../work/vim74/src/testdir/test53.in ./src/testdir/test53.in --- ../../work/vim74/src/testdir/test53.in 2013-06-30 15:31:56.000000000 +0300 +++ ./src/testdir/test53.in 2014-02-22 19:30:41.000000000 +0300 @@ -46,6 +46,9 @@ :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 @@ uniquepattern uniquepattern my very excellent mother just served us nachos for (i=0; i<=10; i++) +Y +text +Y end: diff -ubBwrN ../../work/vim74/src/testdir/test53.ok ./src/testdir/test53.ok --- ../../work/vim74/src/testdir/test53.ok 2013-06-30 15:31:56.000000000 +0300 +++ ./src/testdir/test53.ok 2014-02-22 19:30:41.000000000 +0300 @@ -27,4 +27,7 @@ uniquepattern my very excellent mongoose just served us nachos for (j=0; i<=10; i++) + +text +Y end: diff -ubBwrN ../../work/vim74/src/testdir/test55.in ./src/testdir/test55.in --- ../../work/vim74/src/testdir/test55.in 2013-03-07 16:33:12.000000000 +0300 +++ ./src/testdir/test55.in 2014-02-22 19:30:44.000000000 +0300 @@ -282,6 +282,13 @@ : $put =ps : endfor :endfor +:" :lockvar/islocked() triggering script autoloading +:set rtp+=./sautest +:lockvar g:footest#x +:unlockvar g:footest#x +:$put ='locked g:footest#x:'.islocked('g:footest#x') +:$put ='exists g:footest#x:'.exists('g:footest#x') +:$put ='g:footest#x: '.g:footest#x :" :" a:000 function argument :" first the tests that should fail diff -ubBwrN ../../work/vim74/src/testdir/test55.ok ./src/testdir/test55.ok --- ../../work/vim74/src/testdir/test55.ok 2012-08-29 17:51:15.000000000 +0300 +++ ./src/testdir/test55.ok 2014-02-22 19:30:44.000000000 +0300 @@ -86,6 +86,9 @@ FFpFFpp 0000-000 ppppppp +locked g:footest#x:-1 +exists g:footest#x:0 +g:footest#x: 1 caught a:000 caught a:000[0] caught a:000[2] diff -ubBwrN ../../work/vim74/src/testdir/test60.in ./src/testdir/test60.in --- ../../work/vim74/src/testdir/test60.in 2010-05-15 14:04:10.000000000 +0300 +++ ./src/testdir/test60.in 2014-02-22 19:30:44.000000000 +0300 @@ -1,4 +1,4 @@ -Tests for the exists() function. vim: set ft=vim : +Tests for the exists() function. vim: set ft=vim ts=8 : STARTTEST :so small.vim @@ -11,8 +11,10 @@ endfunction :function! TestExists() augroup myagroup - autocmd! BufEnter *.my echo 'myfile edited' + autocmd! BufEnter *.my echo "myfile edited" + autocmd! FuncUndefined UndefFun exec "fu UndefFun()\nendfu" augroup END + set rtp+=./sautest let test_cases = [] @@ -95,6 +97,11 @@ " Non-existing user defined function let test_cases += [['*MyxyzFunc', 0]] + " Function that may be created by FuncUndefined event + let test_cases += [['*UndefFun', 0]] + " Function that may be created by script autoloading + let test_cases += [['*footest#F', 0]] + redir! > test.out for [test_case, result] in test_cases @@ -207,6 +214,14 @@ echo "FAILED" endif + " Non-existing autoload variable that may be autoloaded + echo 'footest#x: 0' + if !exists('footest#x') + echo "OK" + else + echo "FAILED" + endif + " Valid local list let local_list = ["blue", "orange"] echo 'local_list: 1' @@ -566,6 +581,10 @@ call TestFuncArg("arg1", "arg2") + echo ' g:footest#x =' g:footest#x + echo ' footest#F()' footest#F() + echo 'UndefFun()' UndefFun() + redir END endfunction :call TestExists() @@ -576,5 +595,6 @@ :set ff=unix :w :qa! +:while getchar(1) | call getchar() | endwhile ENDTEST diff -ubBwrN ../../work/vim74/src/testdir/test60.ok ./src/testdir/test60.ok --- ../../work/vim74/src/testdir/test60.ok 2010-05-15 14:04:10.000000000 +0300 +++ ./src/testdir/test60.ok 2014-02-22 19:30:44.000000000 +0300 @@ -71,6 +71,10 @@ OK *MyxyzFunc: 0 OK +*UndefFun: 0 +OK +*footest#F: 0 +OK :edit: 2 OK :edit/a: 0 @@ -95,6 +99,8 @@ OK local_var: 0 OK +footest#x: 0 +OK local_list: 1 OK local_list[1]: 1 @@ -195,3 +201,6 @@ OK a:2: 0 OK + g:footest#x = 1 + footest#F() 0 +UndefFun() 0 diff -ubBwrN ../../work/vim74/src/testdir/test64.in ./src/testdir/test64.in --- ../../work/vim74/src/testdir/test64.in 2013-08-01 18:45:33.000000000 +0300 +++ ./src/testdir/test64.in 2014-02-22 19:30:43.000000000 +0300 @@ -289,15 +289,29 @@ :call add(tl, [2, '.a\%$', " a\n "]) :call add(tl, [2, '.a\%$', " a\n_a", "_a"]) :" -:"""" Test recognition of some character classes -:call add(tl, [2, '[0-9]', '8', '8']) -:call add(tl, [2, '[^0-9]', '8']) -:call add(tl, [2, '[0-9a-fA-F]*', '0a7', '0a7']) -:call add(tl, [2, '[^0-9A-Fa-f]\+', '0a7']) -:call add(tl, [2, '[a-z_A-Z0-9]\+', 'aso_sfoij', 'aso_sfoij']) -:call add(tl, [2, '[a-z]', 'a', 'a']) -:call add(tl, [2, '[a-zA-Z]', 'a', 'a']) -:call add(tl, [2, '[A-Z]', 'a']) +:"""" Test recognition of character classes +:call add(tl, [2, '[0-7]\+', 'x0123456789x', '01234567']) +:call add(tl, [2, '[^0-7]\+', '0a;X+% 897', 'a;X+% 89']) +:call add(tl, [2, '[0-9]\+', 'x0123456789x', '0123456789']) +:call add(tl, [2, '[^0-9]\+', '0a;X+% 9', 'a;X+% ']) +:call add(tl, [2, '[0-9a-fA-F]\+', 'x0189abcdefg', '0189abcdef']) +:call add(tl, [2, '[^0-9A-Fa-f]\+', '0189g;X+% ab', 'g;X+% ']) +:call add(tl, [2, '[a-z_A-Z0-9]\+', ';+aso_SfOij ', 'aso_SfOij']) +:call add(tl, [2, '[^a-z_A-Z0-9]\+', 'aSo_;+% sfOij', ';+% ']) +:call add(tl, [2, '[a-z_A-Z]\+', '0abyz_ABYZ;', 'abyz_ABYZ']) +:call add(tl, [2, '[^a-z_A-Z]\+', 'abAB_09;+% yzYZ', '09;+% ']) +:call add(tl, [2, '[a-z]\+', '0abcxyz1', 'abcxyz']) +:call add(tl, [2, '[a-z]\+', 'AabxyzZ', 'abxyz']) +:call add(tl, [2, '[^a-z]\+', 'a;X09+% x', ';X09+% ']) +:call add(tl, [2, '[^a-z]\+', 'abX0;%yz', 'X0;%']) +:call add(tl, [2, '[a-zA-Z]\+', '0abABxzXZ9', 'abABxzXZ']) +:call add(tl, [2, '[^a-zA-Z]\+', 'ab09_;+ XZ', '09_;+ ']) +:call add(tl, [2, '[A-Z]\+', 'aABXYZz', 'ABXYZ']) +:call add(tl, [2, '[^A-Z]\+', 'ABx0;%YZ', 'x0;%']) +:call add(tl, [2, '[a-z]\+\c', '0abxyzABXYZ;', 'abxyzABXYZ']) +:call add(tl, [2, '[A-Z]\+\c', '0abABxzXZ9', 'abABxzXZ']) +:call add(tl, [2, '\c[^a-z]\+', 'ab09_;+ XZ', '09_;+ ']) +:call add(tl, [2, '\c[^A-Z]\+', 'ab09_;+ XZ', '09_;+ ']) :call add(tl, [2, '\C[^A-Z]\+', 'ABCOIJDEOIFNSD jsfoij sa', ' jsfoij sa']) :" :"""" Tests for \z features @@ -314,6 +328,7 @@ :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']) @@ -358,6 +373,7 @@ :call add(tl, [2, '\%x20', 'yes no', ' ']) :call add(tl, [2, '\%u0020', 'yes no', ' ']) :call add(tl, [2, '\%U00000020', 'yes no', ' ']) +:call add(tl, [2, '\%d0', "yes\x0ano", "\x0a"]) :" :""""" \%[abc] :call add(tl, [2, 'foo\%[bar]', 'fobar']) @@ -390,6 +406,7 @@ :call add(tl, [2, '^.*\.\(.*\)/.\+\(\1\)\@', 'barfoo', '', 'foo']) :call add(tl, [2, '\(foo\)\@<=.*', 'foobar', 'bar', 'foo']) :" +:" 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']) :" @@ -484,6 +507,8 @@ :" Check a pattern with a line break and ^ and $ :call add(tl, [2, 'a\n^b$\n^c', ['a', 'b', 'c'], ['XX']]) :" +:call add(tl, [2, '\(^.\+\n\)\1', [' dog', ' dog', 'asdf'], ['XXasdf']]) +:" :"""" Run the multi-line tests :" :$put ='multi-line tests' diff -ubBwrN ../../work/vim74/src/testdir/test64.ok ./src/testdir/test64.ok --- ../../work/vim74/src/testdir/test64.ok 2013-08-01 19:28:56.000000000 +0300 +++ ./src/testdir/test64.ok 2014-02-22 19:30:43.000000000 +0300 @@ -650,30 +650,72 @@ OK 0 - .a\%$ OK 1 - .a\%$ OK 2 - .a\%$ -OK 0 - [0-9] -OK 1 - [0-9] -OK 2 - [0-9] -OK 0 - [^0-9] -OK 1 - [^0-9] -OK 2 - [^0-9] -OK 0 - [0-9a-fA-F]* -OK 1 - [0-9a-fA-F]* -OK 2 - [0-9a-fA-F]* +OK 0 - [0-7]\+ +OK 1 - [0-7]\+ +OK 2 - [0-7]\+ +OK 0 - [^0-7]\+ +OK 1 - [^0-7]\+ +OK 2 - [^0-7]\+ +OK 0 - [0-9]\+ +OK 1 - [0-9]\+ +OK 2 - [0-9]\+ +OK 0 - [^0-9]\+ +OK 1 - [^0-9]\+ +OK 2 - [^0-9]\+ +OK 0 - [0-9a-fA-F]\+ +OK 1 - [0-9a-fA-F]\+ +OK 2 - [0-9a-fA-F]\+ OK 0 - [^0-9A-Fa-f]\+ OK 1 - [^0-9A-Fa-f]\+ OK 2 - [^0-9A-Fa-f]\+ OK 0 - [a-z_A-Z0-9]\+ OK 1 - [a-z_A-Z0-9]\+ OK 2 - [a-z_A-Z0-9]\+ -OK 0 - [a-z] -OK 1 - [a-z] -OK 2 - [a-z] -OK 0 - [a-zA-Z] -OK 1 - [a-zA-Z] -OK 2 - [a-zA-Z] -OK 0 - [A-Z] -OK 1 - [A-Z] -OK 2 - [A-Z] +OK 0 - [^a-z_A-Z0-9]\+ +OK 1 - [^a-z_A-Z0-9]\+ +OK 2 - [^a-z_A-Z0-9]\+ +OK 0 - [a-z_A-Z]\+ +OK 1 - [a-z_A-Z]\+ +OK 2 - [a-z_A-Z]\+ +OK 0 - [^a-z_A-Z]\+ +OK 1 - [^a-z_A-Z]\+ +OK 2 - [^a-z_A-Z]\+ +OK 0 - [a-z]\+ +OK 1 - [a-z]\+ +OK 2 - [a-z]\+ +OK 0 - [a-z]\+ +OK 1 - [a-z]\+ +OK 2 - [a-z]\+ +OK 0 - [^a-z]\+ +OK 1 - [^a-z]\+ +OK 2 - [^a-z]\+ +OK 0 - [^a-z]\+ +OK 1 - [^a-z]\+ +OK 2 - [^a-z]\+ +OK 0 - [a-zA-Z]\+ +OK 1 - [a-zA-Z]\+ +OK 2 - [a-zA-Z]\+ +OK 0 - [^a-zA-Z]\+ +OK 1 - [^a-zA-Z]\+ +OK 2 - [^a-zA-Z]\+ +OK 0 - [A-Z]\+ +OK 1 - [A-Z]\+ +OK 2 - [A-Z]\+ +OK 0 - [^A-Z]\+ +OK 1 - [^A-Z]\+ +OK 2 - [^A-Z]\+ +OK 0 - [a-z]\+\c +OK 1 - [a-z]\+\c +OK 2 - [a-z]\+\c +OK 0 - [A-Z]\+\c +OK 1 - [A-Z]\+\c +OK 2 - [A-Z]\+\c +OK 0 - \c[^a-z]\+ +OK 1 - \c[^a-z]\+ +OK 2 - \c[^a-z]\+ +OK 0 - \c[^A-Z]\+ +OK 1 - \c[^A-Z]\+ +OK 2 - \c[^A-Z]\+ OK 0 - \C[^A-Z]\+ OK 1 - \C[^A-Z]\+ OK 2 - \C[^A-Z]\+ @@ -710,6 +752,9 @@ 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\@= @@ -818,6 +863,9 @@ OK 0 - \%U00000020 OK 1 - \%U00000020 OK 2 - \%U00000020 +OK 0 - \%d0 +OK 1 - \%d0 +OK 2 - \%d0 OK 0 - foo\%[bar] OK 1 - foo\%[bar] OK 2 - foo\%[bar] @@ -896,6 +944,9 @@ OK 0 - \\\@a OK 1 - \(a*\)\@>a 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 - \(.\{-}\)\(\)\@>$ +OK 1 - \(.\{-}\)\(\)\@>$ +OK 2 - \(.\{-}\)\(\)\@>$ OK 0 - \(a*\)\@>a\|a\+ OK 2 - \(a*\)\@>a\|a\+ OK 0 - \_[^8-9]\+ @@ -968,6 +1031,9 @@ OK 0 - a\n^b$\n^c OK 1 - a\n^b$\n^c OK 2 - a\n^b$\n^c +OK 0 - \(^.\+\n\)\1 +OK 1 - \(^.\+\n\)\1 +OK 2 - \(^.\+\n\)\1 Ta 5 Ac 7 diff -ubBwrN ../../work/vim74/src/testdir/test68.in ./src/testdir/test68.in --- ../../work/vim74/src/testdir/test68.in 2012-07-25 16:57:06.000000000 +0300 +++ ./src/testdir/test68.in 2014-02-22 19:30:41.000000000 +0300 @@ -62,6 +62,20 @@ } STARTTEST +/^{/+3 +:set tw=5 fo=t2a si +i A_ +ENDTEST + +{ + + x a + b + c + +} + +STARTTEST /^{/+1 :set tw=5 fo=qn comments=:# gwap diff -ubBwrN ../../work/vim74/src/testdir/test68.ok ./src/testdir/test68.ok --- ../../work/vim74/src/testdir/test68.ok 2012-07-25 17:03:05.000000000 +0300 +++ ./src/testdir/test68.ok 2014-02-22 19:30:41.000000000 +0300 @@ -43,6 +43,15 @@ { + + x a + b_ + c + +} + + +{ # 1 a # b } diff -ubBwrN ../../work/vim74/src/testdir/test69.in ./src/testdir/test69.in --- ../../work/vim74/src/testdir/test69.in 2013-03-07 20:30:50.000000000 +0300 +++ ./src/testdir/test69.in 2014-02-22 19:30:41.000000000 +0300 @@ -1,6 +1,7 @@ Test for multi-byte text formatting. Also test, that 'mps' with multibyte chars works. And test "ra" on multi-byte characters. +Also test byteidx() and byteidxcomp() STARTTEST :so mbyte.vim @@ -154,6 +155,21 @@ aab STARTTEST +:let a = '.é.' " one char of two bytes +:let b = '.é.' " normal e with composing char +/^byteidx +:put =string([byteidx(a, 0), byteidx(a, 1), byteidx(a, 2), byteidx(a, 3), byteidx(a, 4)]) +:put =string([byteidx(b, 0), byteidx(b, 1), byteidx(b, 2), byteidx(b, 3), byteidx(b, 4)]) +/^byteidxcomp +:put =string([byteidxcomp(a, 0), byteidxcomp(a, 1), byteidxcomp(a, 2), byteidxcomp(a, 3), byteidxcomp(a, 4)]) +:let b = '.é.' +:put =string([byteidxcomp(b, 0), byteidxcomp(b, 1), byteidxcomp(b, 2), byteidxcomp(b, 3), byteidxcomp(b, 4), byteidxcomp(b, 5)]) +ENDTEST + +byteidx +byteidxcomp + +STARTTEST :g/^STARTTEST/.,/^ENDTEST/d :1;/^Results/,$wq! test.out ENDTEST diff -ubBwrN ../../work/vim74/src/testdir/test69.ok ./src/testdir/test69.ok --- ../../work/vim74/src/testdir/test69.ok 2013-03-07 20:31:32.000000000 +0300 +++ ./src/testdir/test69.ok 2014-02-22 19:30:41.000000000 +0300 @@ -149,3 +149,11 @@ aaaa aaa + +byteidx +[0, 1, 3, 4, -1] +[0, 1, 4, 5, -1] +byteidxcomp +[0, 1, 3, 4, -1] +[0, 1, 2, 4, 5, -1] + diff -ubBwrN ../../work/vim74/src/testdir/test75.in ./src/testdir/test75.in --- ../../work/vim74/src/testdir/test75.in 2013-06-29 14:48:42.000000000 +0300 +++ ./src/testdir/test75.in 2014-02-22 19:30:41.000000000 +0300 @@ -1,4 +1,4 @@ -" Tests for functions. +Tests for maparg(). STARTTEST :so small.vim diff -ubBwrN ../../work/vim74/src/testdir/test80.in ./src/testdir/test80.in --- ../../work/vim74/src/testdir/test80.in 2013-03-19 19:30:51.000000000 +0300 +++ ./src/testdir/test80.in 2014-02-22 19:30:45.000000000 +0300 @@ -142,6 +142,8 @@ :$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 @@ -174,6 +176,23 @@ TEST_10: STARTTEST +:set magic& +:set cpo& +:$put =\"\n\nTEST_10:\" +:let y = substitute('123', '\zs', 'a', 'g') | $put =y +:let y = substitute('123', '\zs.', 'a', 'g') | $put =y +:let y = substitute('123', '.\zs', 'a', 'g') | $put =y +:let y = substitute('123', '\ze', 'a', 'g') | $put =y +:let y = substitute('123', '\ze.', 'a', 'g') | $put =y +:let y = substitute('123', '.\ze', 'a', 'g') | $put =y +:let y = substitute('123', '1\|\ze', 'a', 'g') | $put =y +:let y = substitute('123', '1\zs\|[23]', 'a', 'g') | $put =y +/^TEST_11 +ENDTEST + +TEST_11: + +STARTTEST :/^Results/,$wq! test.out ENDTEST diff -ubBwrN ../../work/vim74/src/testdir/test80.ok ./src/testdir/test80.ok --- ../../work/vim74/src/testdir/test80.ok 2013-03-19 19:31:45.000000000 +0300 +++ ./src/testdir/test80.ok 2014-02-22 19:30:45.000000000 +0300 @@ -103,6 +103,8 @@ A A B B +-abab +c-cbcbc TEST_8: @@ -113,3 +115,14 @@ TEST_9: XXx + + +TEST_10: +a1a2a3a +aaa +1a2a3a +a1a2a3a +a1a2a3 +aaa +aa2a3a +1aaa diff -ubBwrN ../../work/vim74/src/testdir/test86.in ./src/testdir/test86.in --- ../../work/vim74/src/testdir/test86.in 2013-07-13 15:00:31.000000000 +0300 +++ ./src/testdir/test86.in 2014-02-22 19:30:45.000000000 +0300 @@ -39,6 +39,7 @@ py << EOF d=vim.bindeval('d') d['1']='asd' +d.update() # Must not do anything, including throwing errors d.update(b=[1, 2, f]) d.update((('-1', {'a': 1}),)) d.update({'0': -1}) @@ -135,6 +136,18 @@ :py l=vim.bindeval('l') :py del l[-6:2] :$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py del l[::2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py del l[3:0:-2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py l=vim.bindeval('l') +:py del l[2:4:-2] +:$put =string(l) :" :" Slice assignment to a list :let l = [0, 1, 2, 3] @@ -169,6 +182,26 @@ :py l=vim.bindeval('l') :py l[0:0]=['h'] :$put =string(l) +:let l = range(8) +:py l=vim.bindeval('l') +:py l[2:6:2] = [10, 20] +:$put =string(l) +:let l = range(8) +:py l=vim.bindeval('l') +:py l[6:2:-2] = [10, 20] +:$put =string(l) +:let l = range(8) +:py l=vim.bindeval('l') +:py l[6:2] = () +:$put =string(l) +:let l = range(8) +:py l=vim.bindeval('l') +:py l[6:2:1] = () +:$put =string(l) +:let l = range(8) +:py l=vim.bindeval('l') +:py l[2:2:1] = () +:$put =string(l) :" :" Locked variables :let l = [0, 1, 2, 3] @@ -179,6 +212,32 @@ :unlockvar! l :" :" Function calls +py << EOF +import sys +def ee(expr, g=globals(), l=locals()): + try: + exec(expr, g, l) + except: + ei = sys.exc_info() + msg = sys.exc_info()[0].__name__ + ':' + repr(sys.exc_info()[1].args) + msg = msg.replace('TypeError:(\'argument 1 ', 'TypeError:(\'') + if expr.find('None') > -1: + msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', + 'TypeError:("\'NoneType\' object is not iterable",)') + if expr.find('FailingNumber') > -1: + msg = msg.replace(', not \'FailingNumber\'', '').replace('"', '\'') + msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', + 'TypeError:("\'FailingNumber\' object is not iterable",)') + if msg.find('(\'\'') > -1 or msg.find('(\'can\'t') > -1: + msg = msg.replace('(\'', '("').replace('\',)', '",)') + if expr == 'fd(self=[])': + # HACK: PyMapping_Check changed meaning + msg = msg.replace('AttributeError:(\'keys\',)', + 'TypeError:(\'unable to convert list to vim dictionary\',)') + vim.current.buffer.append(expr + ':' + msg) + else: + vim.current.buffer.append(expr + ':NOT FAILED') +EOF :fun New(...) : return ['NewStart']+a:000+['NewEnd'] :endfun @@ -193,18 +252,10 @@ :$put =string(l) :py l.extend([l[0].name]) :$put =string(l) -:try -: py l[1](1, 2, 3) -:catch -: $put =v:exception[:16] -:endtry +:py ee('l[1](1, 2, 3)') :py f=l[0] :delfunction New -:try -: py f(1, 2, 3) -:catch -: $put =v:exception[:16] -:endtry +:py ee('f(1, 2, 3)') :if has('float') : let l=[0.0] : py l=vim.bindeval('l') @@ -216,7 +267,6 @@ :let messages=[] :delfunction DictNew py < 8 # check if the background thread is working :py del time :py del threading +:py del t :$put =string(l) :" :" settrace @@ -372,6 +423,13 @@ :$put =string(pyeval('l')) :py l = ll[-10:10] :$put =string(pyeval('l')) +:py l = ll[4:2:-1] +:$put =string(pyeval('l')) +:py l = ll[::2] +:$put =string(pyeval('l')) +:py l = ll[4:2:1] +:$put =string(pyeval('l')) +:py del l :" :" Vars :let g:foo = 'bac' @@ -449,6 +507,11 @@ :py bopts1=vim.buffers[vim.bindeval("g:bufs")[2]].options :py bopts2=vim.buffers[vim.bindeval("g:bufs")[1]].options :py bopts3=vim.buffers[vim.bindeval("g:bufs")[0]].options +:$put ='wopts iters equal: '.pyeval('list(wopts1) == list(wopts2)') +:$put ='bopts iters equal: '.pyeval('list(bopts1) == list(bopts2)') +:py gset=set(iter(gopts1)) +:py wset=set(iter(wopts1)) +:py bset=set(iter(bopts1)) :set path=.,..,, :let lst=[] :let lst+=[['paste', 1, 0, 1, 2, 1, 1, 0 ]] @@ -479,6 +542,8 @@ : py oval3=bool(oval3) : endif : put ='>>> '.oname +: $put =' g/w/b:'.pyeval('oname in gset').'/'.pyeval('oname in wset').'/'.pyeval('oname in bset') +: $put =' g/w/b (in):'.pyeval('oname in gopts1').'/'.pyeval('oname in wopts1').'/'.pyeval('oname in bopts1') : for v in ['gopts1', 'wopts1', 'bopts1'] : try : put =' p/'.v.': '.Ev('repr('.v.'['''.oname.'''])') @@ -882,29 +947,6 @@ :fun D() :endfun py << EOF -def ee(expr, g=globals(), l=locals()): - try: - exec(expr, g, l) - except: - ei = sys.exc_info() - msg = sys.exc_info()[0].__name__ + ':' + repr(sys.exc_info()[1].args) - msg = msg.replace('TypeError:(\'argument 1 ', 'TypeError:(\'') - if expr.find('None') > -1: - msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', - 'TypeError:("\'NoneType\' object is not iterable",)') - if expr.find('FailingNumber') > -1: - msg = msg.replace(', not \'FailingNumber\'', '').replace('"', '\'') - msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', - 'TypeError:("\'FailingNumber\' object is not iterable",)') - if msg.find('(\'\'') > -1 or msg.find('(\'can\'t') > -1: - msg = msg.replace('(\'', '("').replace('\',)', '",)') - if expr == 'fd(self=[])': - # HACK: PyMapping_Check changed meaning - msg = msg.replace('AttributeError:(\'keys\',)', - 'TypeError:(\'unable to convert list to vim dictionary\',)') - cb.append(expr + ':' + msg) - else: - cb.append(expr + ':NOT FAILED') d = vim.Dictionary() ned = vim.Dictionary(foo='bar', baz='abcD') dl = vim.Dictionary(a=1) @@ -912,6 +954,7 @@ l = vim.List() ll = vim.List('abcE') ll.locked = True +nel = vim.List('abcO') f = vim.Function('string') fd = vim.Function('F') fdel = vim.Function('D') @@ -999,6 +1042,20 @@ def next(self): raise NotImplementedError('next') +class FailingIterNextN(object): + def __init__(self, n): + self.n = n + + def __iter__(self): + return self + + def next(self): + if self.n: + self.n -= 1 + return 1 + else: + raise NotImplementedError('next N') + class FailingMappingKey(object): def __getitem__(self, item): raise NotImplementedError('getitem:mappingkey') @@ -1073,6 +1130,13 @@ ee('import failing') vim.options['rtp'] = old_rtp del old_rtp +cb.append("> Options") +cb.append(">> OptionsItem") +ee('vim.options["abcQ"]') +ee('vim.options[""]') +stringtochars_test('vim.options[%s]') +cb.append(">> OptionsContains") +stringtochars_test('%s in vim.options') cb.append("> Dictionary") cb.append(">> DictionaryConstructor") ee('vim.Dictionary("abcI")') @@ -1088,6 +1152,9 @@ stringtochars_test('d.get(%s)') ee('d.pop("a")') ee('dl.pop("a")') +cb.append(">> DictionaryContains") +ee('"" in d') +ee('0 in d') cb.append(">> DictionaryIterNext") ee('for i in ned: ned["a"] = 1') del i @@ -1100,6 +1167,7 @@ cb.append(">>> iter") ee('d.update(FailingMapping())') ee('d.update([FailingIterNext()])') +ee('d.update([FailingIterNextN(1)])') iter_test('d.update(%s)') convertfrompyobject_test('d.update(%s)') stringtochars_test('d.update(((%s, 0),))') @@ -1122,6 +1190,14 @@ cb.append(">> ListAssSlice") ee('ll[1:100] = "abcJ"') iter_test('l[:] = %s') +ee('nel[1:10:2] = "abcK"') +cb.append(repr(tuple(nel))) +ee('nel[1:10:2] = "a"') +cb.append(repr(tuple(nel))) +ee('nel[1:1:-1] = "a"') +cb.append(repr(tuple(nel))) +ee('nel[:] = FailingIterNextN(2)') +cb.append(repr(tuple(nel))) convertfrompyobject_test('l[:] = [%s]') cb.append(">> ListConcatInPlace") iter_test('l.extend(%s)') @@ -1203,6 +1279,7 @@ del dl del l del ll +del nel del f del fd del fdel @@ -1216,6 +1293,7 @@ del FailingTrue del FailingIter del FailingIterNext +del FailingIterNextN del FailingMapping del FailingMappingKey del FailingList @@ -1273,11 +1351,43 @@ ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")') ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")') ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")') +ee('vim.eval("xxx_unknown_function_xxx()")') ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")') del Exe EOF :delfunction Exe :" +:" Regression: interrupting vim.command propagates to next vim.command +py << EOF +def test_keyboard_interrupt(): + try: + vim.command('while 1 | endwhile') + except KeyboardInterrupt: + cb.append('Caught KeyboardInterrupt') + except Exception: + cb.append('!!!!!!!! Caught exception: ' + repr(sys.exc_info)) + else: + cb.append('!!!!!!!! No exception') + try: + vim.command('$ put =\'Running :put\'') + except KeyboardInterrupt: + cb.append('!!!!!!!! Caught KeyboardInterrupt') + except Exception: + cb.append('!!!!!!!! Caught exception: ' + repr(sys.exc_info)) + else: + cb.append('No exception') +EOF +:debuggreedy +:call inputsave() +:call feedkeys("s\ns\ns\ns\nq\n") +:redir => output +:debug silent! py test_keyboard_interrupt() +:redir END +:0 debuggreedy +:silent $put =output +:unlet output +:py del test_keyboard_interrupt +:" :" Cleanup py << EOF del cb diff -ubBwrN ../../work/vim74/src/testdir/test86.ok ./src/testdir/test86.ok --- ../../work/vim74/src/testdir/test86.ok 2013-06-23 17:38:39.000000000 +0300 +++ ./src/testdir/test86.ok 2014-02-22 19:30:45.000000000 +0300 @@ -41,6 +41,9 @@ [2, 3] [2, 3] [2, 3] +[1, 3] +[0, 2] +[0, 1, 2, 3] ['a', 0, 1, 2, 3] [0, 'b', 2, 3] [0, 1, 'c'] @@ -49,12 +52,17 @@ ['f', 2, 3] [0, 1, 'g', 2, 3] ['h'] +[0, 1, 10, 3, 20, 5, 6, 7] +[0, 1, 2, 3, 20, 5, 10, 7] +[0, 1, 2, 3, 4, 5, 6, 7] +[0, 1, 2, 3, 4, 5, 6, 7] +[0, 1, 2, 3, 4, 5, 6, 7] [0, 1, 2, 3] [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd'] [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}] [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}, 'New'] -Vim(python):E725: -Vim(python):E117: +l[1](1, 2, 3):error:('Vim:E725: Calling dict function without Dictionary: DictNew',) +f(1, 2, 3):error:('Vim:E117: Unknown function: New',) [0.0, 0.0] KeyError TypeError @@ -96,12 +104,19 @@ [0, 1, 2, 3, 4, 5] [0, 1, 2, 3, 4, 5] [0, 1, 2, 3, 4, 5] +[4, 3] +[0, 2, 4] +[] Abc bac def bar jkl +wopts iters equal: 1 +bopts iters equal: 1 >>> paste + g/w/b:1/0/0 + g/w/b (in):1/0/0 p/gopts1: False p/wopts1! KeyError inv: 2! KeyError @@ -122,6 +137,8 @@ W: 1:1 2:1 3:1 4:1 B: 1:1 2:1 3:1 4:1 >>> previewheight + g/w/b:1/0/0 + g/w/b (in):1/0/0 p/gopts1: 12 inv: 'a'! TypeError p/wopts1! KeyError @@ -143,6 +160,8 @@ W: 1:5 2:5 3:5 4:5 B: 1:5 2:5 3:5 4:5 >>> operatorfunc + g/w/b:1/0/0 + g/w/b (in):1/0/0 p/gopts1: '' inv: 2! TypeError p/wopts1! KeyError @@ -164,6 +183,8 @@ W: 1:'A' 2:'A' 3:'A' 4:'A' B: 1:'A' 2:'A' 3:'A' 4:'A' >>> number + g/w/b:0/1/0 + g/w/b (in):0/1/0 p/gopts1! KeyError inv: 0! KeyError gopts1! KeyError @@ -182,6 +203,8 @@ W: 1:1 2:1 3:0 4:0 B: 1:1 2:1 3:0 4:0 >>> numberwidth + g/w/b:0/1/0 + g/w/b (in):0/1/0 p/gopts1! KeyError inv: -100! KeyError gopts1! KeyError @@ -201,6 +224,8 @@ W: 1:3 2:5 3:2 4:8 B: 1:3 2:5 3:2 4:8 >>> colorcolumn + g/w/b:0/1/0 + g/w/b (in):0/1/0 p/gopts1! KeyError inv: 'abc4'! KeyError gopts1! KeyError @@ -220,6 +245,8 @@ W: 1:'+2' 2:'+3' 3:'+1' 4:'' B: 1:'+2' 2:'+3' 3:'+1' 4:'' >>> statusline + g/w/b:1/1/0 + g/w/b (in):1/1/0 p/gopts1: '' inv: 0! TypeError p/wopts1: None @@ -237,6 +264,8 @@ W: 1:'2' 2:'1' 3:'1' 4:'1' B: 1:'2' 2:'1' 3:'1' 4:'1' >>> autoindent + g/w/b:0/0/1 + g/w/b (in):0/0/1 p/gopts1! KeyError inv: 2! KeyError gopts1! KeyError @@ -255,6 +284,8 @@ W: 1:0 2:1 3:0 4:1 B: 1:0 2:1 3:0 4:1 >>> shiftwidth + g/w/b:0/0/1 + g/w/b (in):0/0/1 p/gopts1! KeyError inv: 3! KeyError gopts1! KeyError @@ -273,6 +304,8 @@ W: 1:0 2:2 3:8 4:1 B: 1:0 2:2 3:8 4:1 >>> omnifunc + g/w/b:0/0/1 + g/w/b (in):0/0/1 p/gopts1! KeyError inv: 1! KeyError gopts1! KeyError @@ -292,6 +325,8 @@ W: 1:'A' 2:'B' 3:'' 4:'C' B: 1:'A' 2:'B' 3:'' 4:'C' >>> preserveindent + g/w/b:0/0/1 + g/w/b (in):0/0/1 p/gopts1! KeyError inv: 2! KeyError gopts1! KeyError @@ -310,6 +345,8 @@ W: 1:0 2:1 3:0 4:1 B: 1:0 2:1 3:0 4:1 >>> path + g/w/b:1/0/1 + g/w/b (in):1/0/1 p/gopts1: '.,..,,' inv: 0! TypeError p/wopts1! KeyError @@ -498,6 +535,21 @@ import xxx_no_such_module_xxx:ImportError:('No module named xxx_no_such_module_xxx',) import failing_import:ImportError:('No module named failing_import',) import failing:NotImplementedError:() +> Options +>> OptionsItem +vim.options["abcQ"]:KeyError:('abcQ',) +vim.options[""]:ValueError:('empty keys are not allowed',) +>>> Testing StringToChars using vim.options[%s] +vim.options[1]:TypeError:('expected str() or unicode() instance, but got int',) +vim.options[u"\0"]:TypeError:('expected string without null bytes',) +vim.options["\0"]:TypeError:('expected string without null bytes',) +<<< Finished +>> OptionsContains +>>> Testing StringToChars using %s in vim.options +1 in vim.options:TypeError:('expected str() or unicode() instance, but got int',) +u"\0" in vim.options:TypeError:('expected string without null bytes',) +"\0" in vim.options:TypeError:('expected string without null bytes',) +<<< Finished > Dictionary >> DictionaryConstructor vim.Dictionary("abcI"):ValueError:('expected sequence element of size 2, but got sequence of size 1',) @@ -516,6 +568,9 @@ <<< Finished d.pop("a"):KeyError:('a',) dl.pop("a"):error:('dictionary is locked',) +>> DictionaryContains +"" in d:ValueError:('empty keys are not allowed',) +0 in d:TypeError:('expected str() or unicode() instance, but got int',) >> DictionaryIterNext for i in ned: ned["a"] = 1:RuntimeError:('hashtab changed during iteration',) >> DictionaryAssItem @@ -596,6 +651,7 @@ >>> iter d.update(FailingMapping()):NotImplementedError:('keys',) d.update([FailingIterNext()]):NotImplementedError:('next',) +d.update([FailingIterNextN(1)]):NotImplementedError:('next N',) >>> Testing *Iter* using d.update(%s) d.update(FailingIter()):NotImplementedError:('iter',) d.update(FailingIterNext()):NotImplementedError:('next',) @@ -826,6 +882,14 @@ l[:] = FailingIter():NotImplementedError:('iter',) l[:] = FailingIterNext():NotImplementedError:('next',) <<< Finished +nel[1:10:2] = "abcK":ValueError:('attempt to assign sequence of size greater then 2 to extended slice',) +('a', 'b', 'c', 'O') +nel[1:10:2] = "a":ValueError:('attempt to assign sequence of size 1 to extended slice of size 2',) +('a', 'b', 'c', 'O') +nel[1:1:-1] = "a":ValueError:('attempt to assign sequence of size greater then 0 to extended slice',) +('a', 'b', 'c', 'O') +nel[:] = FailingIterNextN(2):NotImplementedError:('next N',) +('a', 'b', 'c', 'O') >>> Testing StringToChars using l[:] = [{%s : 1}] l[:] = [{1 : 1}]:TypeError:('expected str() or unicode() instance, but got int',) l[:] = [{u"\0" : 1}]:TypeError:('expected string without null bytes',) @@ -1194,4 +1258,9 @@ vim.eval("Exe('throw ''ghi''')"):error:('ghi',) vim.eval("Exe('echoerr ''jkl''')"):error:('Vim(echoerr):jkl',) vim.eval("Exe('xxx_non_existent_command_xxx')"):error:('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',) +vim.eval("xxx_unknown_function_xxx()"):error:('Vim:E117: Unknown function: xxx_unknown_function_xxx',) vim.bindeval("Exe('xxx_non_existent_command_xxx')"):error:('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',) +Caught KeyboardInterrupt +Running :put +No exception + diff -ubBwrN ../../work/vim74/src/testdir/test87.in ./src/testdir/test87.in --- ../../work/vim74/src/testdir/test87.in 2013-07-06 14:41:30.000000000 +0300 +++ ./src/testdir/test87.in 2014-02-22 19:30:45.000000000 +0300 @@ -33,6 +33,7 @@ py3 << EOF d=vim.bindeval('d') d['1']='asd' +d.update() # Must not do anything, including throwing errors d.update(b=[1, 2, f]) d.update((('-1', {'a': 1}),)) d.update({'0': -1}) @@ -128,6 +129,18 @@ :py3 l=vim.bindeval('l') :py3 del l[-6:2] :$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 del l[::2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 del l[3:0:-2] +:$put =string(l) +:let l = [0, 1, 2, 3] +:py3 l=vim.bindeval('l') +:py3 del l[2:4:-2] +:$put =string(l) :" :" Slice assignment to a list :let l = [0, 1, 2, 3] @@ -162,6 +175,26 @@ :py3 l=vim.bindeval('l') :py3 l[0:0]=['h'] :$put =string(l) +:let l = range(8) +:py3 l=vim.bindeval('l') +:py3 l[2:6:2] = [10, 20] +:$put =string(l) +:let l = range(8) +:py3 l=vim.bindeval('l') +:py3 l[6:2:-2] = [10, 20] +:$put =string(l) +:let l = range(8) +:py3 l=vim.bindeval('l') +:py3 l[6:2] = () +:$put =string(l) +:let l = range(8) +:py3 l=vim.bindeval('l') +:py3 l[6:2:1] = () +:$put =string(l) +:let l = range(8) +:py3 l=vim.bindeval('l') +:py3 l[2:2:1] = () +:$put =string(l) :" :" Locked variables :let l = [0, 1, 2, 3] @@ -172,6 +205,36 @@ :unlockvar! l :" :" Function calls +py3 << EOF +import sys +import re + +py33_type_error_pattern = re.compile('^__call__\(\) takes (\d+) positional argument but (\d+) were given$') + +def ee(expr, g=globals(), l=locals()): + cb = vim.current.buffer + try: + try: + exec(expr, g, l) + except Exception as e: + if sys.version_info >= (3, 3) and e.__class__ is AttributeError and str(e).find('has no attribute')>=0 and not str(e).startswith("'vim."): + cb.append(expr + ':' + repr((e.__class__, AttributeError(str(e)[str(e).rfind(" '") + 2:-1])))) + elif sys.version_info >= (3, 3) and e.__class__ is ImportError and str(e).find('No module named \'') >= 0: + cb.append(expr + ':' + repr((e.__class__, ImportError(str(e).replace("'", ''))))) + elif sys.version_info >= (3, 3) and e.__class__ is TypeError: + m = py33_type_error_pattern.search(str(e)) + if m: + msg = '__call__() takes exactly {0} positional argument ({1} given)'.format(m.group(1), m.group(2)) + cb.append(expr + ':' + repr((e.__class__, TypeError(msg)))) + else: + cb.append(expr + ':' + repr((e.__class__, e))) + else: + cb.append(expr + ':' + repr((e.__class__, e))) + else: + cb.append(expr + ':NOT FAILED') + except Exception as e: + cb.append(expr + '::' + repr((e.__class__, e))) +EOF :fun New(...) : return ['NewStart']+a:000+['NewEnd'] :endfun @@ -186,18 +249,10 @@ :$put =string(l) :py3 l+=[l[0].name] :$put =string(l) -:try -: py3 l[1](1, 2, 3) -:catch -: $put =v:exception[:13] -:endtry +:py3 ee('l[1](1, 2, 3)') :py3 f=l[0] :delfunction New -:try -: py3 f(1, 2, 3) -:catch -: $put =v:exception[:13] -:endtry +:py3 ee('f(1, 2, 3)') :if has('float') : let l=[0.0] : py3 l=vim.bindeval('l') @@ -315,6 +370,7 @@ :py3 l[0] = t.t > 8 # check if the background thread is working :py3 del time :py3 del threading +:py3 del t :$put =string(l) :" :" settrace @@ -340,6 +396,38 @@ :py3 del trace_main :$put =string(l) :" +:" Slice +:py3 ll = vim.bindeval('[0, 1, 2, 3, 4, 5]') +:py3 l = ll[:4] +:$put =string(py3eval('l')) +:py3 l = ll[2:] +:$put =string(py3eval('l')) +:py3 l = ll[:-4] +:$put =string(py3eval('l')) +:py3 l = ll[-2:] +:$put =string(py3eval('l')) +:py3 l = ll[2:4] +:$put =string(py3eval('l')) +:py3 l = ll[4:2] +:$put =string(py3eval('l')) +:py3 l = ll[-4:-2] +:$put =string(py3eval('l')) +:py3 l = ll[-2:-4] +:$put =string(py3eval('l')) +:py3 l = ll[:] +:$put =string(py3eval('l')) +:py3 l = ll[0:6] +:$put =string(py3eval('l')) +:py3 l = ll[-10:10] +:$put =string(py3eval('l')) +:py3 l = ll[4:2:-1] +:$put =string(py3eval('l')) +:py3 l = ll[::2] +:$put =string(py3eval('l')) +:py3 l = ll[4:2:1] +:$put =string(py3eval('l')) +:py3 del l +:" :" Vars :let g:foo = 'bac' :let w:abc3 = 'def' @@ -416,6 +504,11 @@ :py3 bopts1=vim.buffers[vim.bindeval("g:bufs")[2]].options :py3 bopts2=vim.buffers[vim.bindeval("g:bufs")[1]].options :py3 bopts3=vim.buffers[vim.bindeval("g:bufs")[0]].options +:$put ='wopts iters equal: '.py3eval('list(wopts1) == list(wopts2)') +:$put ='bopts iters equal: '.py3eval('list(bopts1) == list(bopts2)') +:py3 gset=set(iter(gopts1)) +:py3 wset=set(iter(wopts1)) +:py3 bset=set(iter(bopts1)) :set path=.,..,, :let lst=[] :let lst+=[['paste', 1, 0, 1, 2, 1, 1, 0 ]] @@ -446,6 +539,8 @@ : py3 oval3=bool(oval3) : endif : put ='>>> '.oname +: $put =' g/w/b:'.py3eval('oname in gset').'/'.py3eval('oname in wset').'/'.py3eval('oname in bset') +: $put =' g/w/b (in):'.py3eval('oname in gopts1').'/'.py3eval('oname in wopts1').'/'.py3eval('oname in bopts1') : for v in ['gopts1', 'wopts1', 'bopts1'] : try : put =' p/'.v.': '.Ev('repr('.v.'['''.oname.'''])') @@ -829,33 +924,6 @@ :fun D() :endfun py3 << EOF -import re - -py33_type_error_pattern = re.compile('^__call__\(\) takes (\d+) positional argument but (\d+) were given$') - -def ee(expr, g=globals(), l=locals()): - try: - try: - exec(expr, g, l) - except Exception as e: - if sys.version_info >= (3, 3) and e.__class__ is AttributeError and str(e).find('has no attribute')>=0 and not str(e).startswith("'vim."): - cb.append(expr + ':' + repr((e.__class__, AttributeError(str(e)[str(e).rfind(" '") + 2:-1])))) - elif sys.version_info >= (3, 3) and e.__class__ is ImportError and str(e).find('No module named \'') >= 0: - cb.append(expr + ':' + repr((e.__class__, ImportError(str(e).replace("'", ''))))) - elif sys.version_info >= (3, 3) and e.__class__ is TypeError: - m = py33_type_error_pattern.search(str(e)) - if m: - msg = '__call__() takes exactly {0} positional argument ({1} given)'.format(m.group(1), m.group(2)) - cb.append(expr + ':' + repr((e.__class__, TypeError(msg)))) - else: - cb.append(expr + ':' + repr((e.__class__, e))) - else: - cb.append(expr + ':' + repr((e.__class__, e))) - else: - cb.append(expr + ':NOT FAILED') - except Exception as e: - cb.append(expr + '::' + repr((e.__class__, e))) - d = vim.Dictionary() ned = vim.Dictionary(foo='bar', baz='abcD') dl = vim.Dictionary(a=1) @@ -863,6 +931,7 @@ l = vim.List() ll = vim.List('abcE') ll.locked = True +nel = vim.List('abcO') f = vim.Function('string') fd = vim.Function('F') fdel = vim.Function('D') @@ -950,6 +1019,20 @@ def __next__(self): raise NotImplementedError('next') +class FailingIterNextN(object): + def __init__(self, n): + self.n = n + + def __iter__(self): + return self + + def __next__(self): + if self.n: + self.n -= 1 + return 1 + else: + raise NotImplementedError('next N') + class FailingMappingKey(object): def __getitem__(self, item): raise NotImplementedError('getitem:mappingkey') @@ -1024,6 +1107,13 @@ ee('import failing') vim.options['rtp'] = old_rtp del old_rtp +cb.append("> Options") +cb.append(">> OptionsItem") +ee('vim.options["abcQ"]') +ee('vim.options[""]') +stringtochars_test('vim.options[%s]') +cb.append(">> OptionsContains") +stringtochars_test('%s in vim.options') cb.append("> Dictionary") cb.append(">> DictionaryConstructor") ee('vim.Dictionary("abcI")') @@ -1039,6 +1129,9 @@ stringtochars_test('d.get(%s)') ee('d.pop("a")') ee('dl.pop("a")') +cb.append(">> DictionaryContains") +ee('"" in d') +ee('0 in d') cb.append(">> DictionaryIterNext") ee('for i in ned: ned["a"] = 1') del i @@ -1051,6 +1144,7 @@ cb.append(">>> iter") ee('d.update(FailingMapping())') ee('d.update([FailingIterNext()])') +ee('d.update([FailingIterNextN(1)])') iter_test('d.update(%s)') convertfrompyobject_test('d.update(%s)') stringtochars_test('d.update(((%s, 0),))') @@ -1073,6 +1167,14 @@ cb.append(">> ListAssSlice") ee('ll[1:100] = "abcJ"') iter_test('l[:] = %s') +ee('nel[1:10:2] = "abcK"') +cb.append(repr(tuple(nel))) +ee('nel[1:10:2] = "a"') +cb.append(repr(tuple(nel))) +ee('nel[1:1:-1] = "a"') +cb.append(repr(tuple(nel))) +ee('nel[:] = FailingIterNextN(2)') +cb.append(repr(tuple(nel))) convertfrompyobject_test('l[:] = [%s]') cb.append(">> ListConcatInPlace") iter_test('l.extend(%s)') @@ -1154,6 +1256,7 @@ del dl del l del ll +del nel del f del fd del fdel @@ -1167,6 +1270,7 @@ del FailingTrue del FailingIter del FailingIterNext +del FailingIterNextN del FailingMapping del FailingMappingKey del FailingList @@ -1224,11 +1328,43 @@ ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")') ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")') ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")') +ee('vim.eval("xxx_unknown_function_xxx()")') ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")') del Exe EOF :delfunction Exe :" +:" Regression: interrupting vim.command propagates to next vim.command +py3 << EOF +def test_keyboard_interrupt(): + try: + vim.command('while 1 | endwhile') + except KeyboardInterrupt: + cb.append('Caught KeyboardInterrupt') + except Exception as e: + cb.append('!!!!!!!! Caught exception: ' + repr(e)) + else: + cb.append('!!!!!!!! No exception') + try: + vim.command('$ put =\'Running :put\'') + except KeyboardInterrupt: + cb.append('!!!!!!!! Caught KeyboardInterrupt') + except Exception as e: + cb.append('!!!!!!!! Caught exception: ' + repr(e)) + else: + cb.append('No exception') +EOF +:debuggreedy +:call inputsave() +:call feedkeys("s\ns\ns\ns\nq\n") +:redir => output +:debug silent! py3 test_keyboard_interrupt() +:redir END +:0 debuggreedy +:silent $put =output +:unlet output +:py3 del test_keyboard_interrupt +:" :" Cleanup py3 << EOF del cb diff -ubBwrN ../../work/vim74/src/testdir/test87.ok ./src/testdir/test87.ok --- ../../work/vim74/src/testdir/test87.ok 2013-06-23 17:38:39.000000000 +0300 +++ ./src/testdir/test87.ok 2014-02-22 19:30:45.000000000 +0300 @@ -41,6 +41,9 @@ [2, 3] [2, 3] [2, 3] +[1, 3] +[0, 2] +[0, 1, 2, 3] ['a', 0, 1, 2, 3] [0, 'b', 2, 3] [0, 1, 'c'] @@ -49,12 +52,17 @@ ['f', 2, 3] [0, 1, 'g', 2, 3] ['h'] +[0, 1, 10, 3, 20, 5, 6, 7] +[0, 1, 2, 3, 20, 5, 10, 7] +[0, 1, 2, 3, 4, 5, 6, 7] +[0, 1, 2, 3, 4, 5, 6, 7] +[0, 1, 2, 3, 4, 5, 6, 7] [0, 1, 2, 3] [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd'] [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}] [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}, 'New'] -Vim(py3):E725: -Vim(py3):E117: +l[1](1, 2, 3):(, error('Vim:E725: Calling dict function without Dictionary: DictNew',)) +f(1, 2, 3):(, error('Vim:E117: Unknown function: New',)) [0.0, 0.0] KeyError TypeError @@ -85,12 +93,30 @@ vim: Vim(let):E859: [1] [1, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 1] +[0, 1, 2, 3] +[2, 3, 4, 5] +[0, 1] +[4, 5] +[2, 3] +[] +[2, 3] +[] +[0, 1, 2, 3, 4, 5] +[0, 1, 2, 3, 4, 5] +[0, 1, 2, 3, 4, 5] +[4, 3] +[0, 2, 4] +[] Abc bac def bar jkl +wopts iters equal: 1 +bopts iters equal: 1 >>> paste + g/w/b:1/0/0 + g/w/b (in):1/0/0 p/gopts1: False p/wopts1! KeyError inv: 2! KeyError @@ -111,6 +137,8 @@ W: 1:1 2:1 3:1 4:1 B: 1:1 2:1 3:1 4:1 >>> previewheight + g/w/b:1/0/0 + g/w/b (in):1/0/0 p/gopts1: 12 inv: 'a'! TypeError p/wopts1! KeyError @@ -132,6 +160,8 @@ W: 1:5 2:5 3:5 4:5 B: 1:5 2:5 3:5 4:5 >>> operatorfunc + g/w/b:1/0/0 + g/w/b (in):1/0/0 p/gopts1: b'' inv: 2! TypeError p/wopts1! KeyError @@ -153,6 +183,8 @@ W: 1:'A' 2:'A' 3:'A' 4:'A' B: 1:'A' 2:'A' 3:'A' 4:'A' >>> number + g/w/b:0/1/0 + g/w/b (in):0/1/0 p/gopts1! KeyError inv: 0! KeyError gopts1! KeyError @@ -171,6 +203,8 @@ W: 1:1 2:1 3:0 4:0 B: 1:1 2:1 3:0 4:0 >>> numberwidth + g/w/b:0/1/0 + g/w/b (in):0/1/0 p/gopts1! KeyError inv: -100! KeyError gopts1! KeyError @@ -190,6 +224,8 @@ W: 1:3 2:5 3:2 4:8 B: 1:3 2:5 3:2 4:8 >>> colorcolumn + g/w/b:0/1/0 + g/w/b (in):0/1/0 p/gopts1! KeyError inv: 'abc4'! KeyError gopts1! KeyError @@ -209,6 +245,8 @@ W: 1:'+2' 2:'+3' 3:'+1' 4:'' B: 1:'+2' 2:'+3' 3:'+1' 4:'' >>> statusline + g/w/b:1/1/0 + g/w/b (in):1/1/0 p/gopts1: b'' inv: 0! TypeError p/wopts1: None @@ -226,6 +264,8 @@ W: 1:'2' 2:'1' 3:'1' 4:'1' B: 1:'2' 2:'1' 3:'1' 4:'1' >>> autoindent + g/w/b:0/0/1 + g/w/b (in):0/0/1 p/gopts1! KeyError inv: 2! KeyError gopts1! KeyError @@ -244,6 +284,8 @@ W: 1:0 2:1 3:0 4:1 B: 1:0 2:1 3:0 4:1 >>> shiftwidth + g/w/b:0/0/1 + g/w/b (in):0/0/1 p/gopts1! KeyError inv: 3! KeyError gopts1! KeyError @@ -262,6 +304,8 @@ W: 1:0 2:2 3:8 4:1 B: 1:0 2:2 3:8 4:1 >>> omnifunc + g/w/b:0/0/1 + g/w/b (in):0/0/1 p/gopts1! KeyError inv: 1! KeyError gopts1! KeyError @@ -281,6 +325,8 @@ W: 1:'A' 2:'B' 3:'' 4:'C' B: 1:'A' 2:'B' 3:'' 4:'C' >>> preserveindent + g/w/b:0/0/1 + g/w/b (in):0/0/1 p/gopts1! KeyError inv: 2! KeyError gopts1! KeyError @@ -299,6 +345,8 @@ W: 1:0 2:1 3:0 4:1 B: 1:0 2:1 3:0 4:1 >>> path + g/w/b:1/0/1 + g/w/b (in):1/0/1 p/gopts1: b'.,..,,' inv: 0! TypeError p/wopts1! KeyError @@ -487,6 +535,21 @@ import xxx_no_such_module_xxx:(, ImportError('No module named xxx_no_such_module_xxx',)) import failing_import:(, ImportError('No module named failing_import',)) import failing:(, NotImplementedError()) +> Options +>> OptionsItem +vim.options["abcQ"]:(, KeyError('abcQ',)) +vim.options[""]:(, ValueError('empty keys are not allowed',)) +>>> Testing StringToChars using vim.options[%s] +vim.options[1]:(, TypeError('expected bytes() or str() instance, but got int',)) +vim.options[b"\0"]:(, TypeError('expected bytes with no null',)) +vim.options["\0"]:(, TypeError('expected bytes with no null',)) +<<< Finished +>> OptionsContains +>>> Testing StringToChars using %s in vim.options +1 in vim.options:(, TypeError('expected bytes() or str() instance, but got int',)) +b"\0" in vim.options:(, TypeError('expected bytes with no null',)) +"\0" in vim.options:(, TypeError('expected bytes with no null',)) +<<< Finished > Dictionary >> DictionaryConstructor vim.Dictionary("abcI"):(, ValueError('expected sequence element of size 2, but got sequence of size 1',)) @@ -505,6 +568,9 @@ <<< Finished d.pop("a"):(, KeyError('a',)) dl.pop("a"):(, error('dictionary is locked',)) +>> DictionaryContains +"" in d:(, ValueError('empty keys are not allowed',)) +0 in d:(, TypeError('expected bytes() or str() instance, but got int',)) >> DictionaryIterNext for i in ned: ned["a"] = 1:(, RuntimeError('hashtab changed during iteration',)) >> DictionaryAssItem @@ -585,6 +651,7 @@ >>> iter d.update(FailingMapping()):(, NotImplementedError('keys',)) d.update([FailingIterNext()]):(, NotImplementedError('next',)) +d.update([FailingIterNextN(1)]):(, NotImplementedError('next N',)) >>> Testing *Iter* using d.update(%s) d.update(FailingIter()):(, NotImplementedError('iter',)) d.update(FailingIterNext()):(, NotImplementedError('next',)) @@ -815,6 +882,14 @@ l[:] = FailingIter():(, NotImplementedError('iter',)) l[:] = FailingIterNext():(, NotImplementedError('next',)) <<< Finished +nel[1:10:2] = "abcK":(, ValueError('attempt to assign sequence of size greater then 2 to extended slice',)) +(b'a', b'b', b'c', b'O') +nel[1:10:2] = "a":(, ValueError('attempt to assign sequence of size 1 to extended slice of size 2',)) +(b'a', b'b', b'c', b'O') +nel[1:1:-1] = "a":(, ValueError('attempt to assign sequence of size greater then 0 to extended slice',)) +(b'a', b'b', b'c', b'O') +nel[:] = FailingIterNextN(2):(, NotImplementedError('next N',)) +(b'a', b'b', b'c', b'O') >>> Testing StringToChars using l[:] = [{%s : 1}] l[:] = [{1 : 1}]:(, TypeError('expected bytes() or str() instance, but got int',)) l[:] = [{b"\0" : 1}]:(, TypeError('expected bytes with no null',)) @@ -1183,4 +1258,9 @@ vim.eval("Exe('throw ''ghi''')"):(, error('ghi',)) vim.eval("Exe('echoerr ''jkl''')"):(, error('Vim(echoerr):jkl',)) vim.eval("Exe('xxx_non_existent_command_xxx')"):(, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',)) +vim.eval("xxx_unknown_function_xxx()"):(, error('Vim:E117: Unknown function: xxx_unknown_function_xxx',)) vim.bindeval("Exe('xxx_non_existent_command_xxx')"):(, error('Vim:E492: Not an editor command: xxx_non_existent_command_xxx',)) +Caught KeyboardInterrupt +Running :put +No exception + diff -ubBwrN ../../work/vim74/src/testdir/test92.in ./src/testdir/test92.in --- ../../work/vim74/src/testdir/test92.in 2013-04-19 00:33:45.000000000 +0300 +++ ./src/testdir/test92.in 2014-02-22 19:30:40.000000000 +0300 @@ -33,7 +33,7 @@ :mksession! test.out :new test.out :v/\(^ *normal! 0\|^ *exe 'normal!\)/d -:w +:w! test.out :qa! ENDTEST diff -ubBwrN ../../work/vim74/src/testdir/test93.in ./src/testdir/test93.in --- ../../work/vim74/src/testdir/test93.in 2013-02-26 19:13:01.000000000 +0300 +++ ./src/testdir/test93.in 2014-02-22 19:30:40.000000000 +0300 @@ -33,7 +33,7 @@ :mksession! test.out :new test.out :v/\(^ *normal! 0\|^ *exe 'normal!\)/d -:w +:w! test.out :qa! ENDTEST diff -ubBwrN ../../work/vim74/src/undo.c ./src/undo.c --- ../../work/vim74/src/undo.c 2013-06-10 21:13:37.000000000 +0300 +++ ./src/undo.c 2014-02-22 19:30:45.000000000 +0300 @@ -83,6 +83,7 @@ #include "vim.h" +static long get_undolevel __ARGS((void)); static void u_unch_branch __ARGS((u_header_T *uhp)); static u_entry_T *u_get_headentry __ARGS((void)); static void u_getbot __ARGS((void)); @@ -336,6 +337,17 @@ } /* + * Get the undolevle value for the current buffer. + */ + static long +get_undolevel() +{ + if (curbuf->b_p_ul == NO_LOCAL_UNDOLEVEL) + return p_ul; + return curbuf->b_p_ul; +} + +/* * Common code for various ways to save text before a change. * "top" is the line above the first changed line. * "bot" is the line below the last changed line. @@ -397,7 +409,7 @@ { /* This happens when the FileChangedRO autocommand changes the * file in a way it becomes shorter. */ - EMSG(_("E834: Line count changed unexpectedly")); + EMSG(_("E881: Line count changed unexpectedly")); return FAIL; } #endif @@ -419,7 +431,7 @@ curbuf->b_new_change = TRUE; #endif - if (p_ul >= 0) + if (get_undolevel() >= 0) { /* * Make a new header entry. Do this first so that we don't mess @@ -449,7 +461,8 @@ /* * free headers to keep the size right */ - while (curbuf->b_u_numhead > p_ul && curbuf->b_u_oldhead != NULL) + while (curbuf->b_u_numhead > get_undolevel() + && curbuf->b_u_oldhead != NULL) { u_header_T *uhfree = curbuf->b_u_oldhead; @@ -530,7 +543,7 @@ } else { - if (p_ul < 0) /* no undo at all */ + if (get_undolevel() < 0) /* no undo at all */ return OK; /* @@ -1604,10 +1617,11 @@ #ifdef UNIX /* For safety we only read an undo file if the owner is equal to the - * owner of the text file. */ + * owner of the text file or equal to the current user. */ if (mch_stat((char *)orig_name, &st_orig) >= 0 && mch_stat((char *)file_name, &st_undo) >= 0 - && st_orig.st_uid != st_undo.st_uid) + && st_orig.st_uid != st_undo.st_uid + && st_undo.st_uid != getuid()) { if (p_verbose > 0) { @@ -1971,7 +1985,7 @@ { if (curbuf->b_u_curhead == NULL) /* first undo */ curbuf->b_u_curhead = curbuf->b_u_newhead; - else if (p_ul > 0) /* multi level undo */ + else if (get_undolevel() > 0) /* multi level undo */ /* get next undo */ curbuf->b_u_curhead = curbuf->b_u_curhead->uh_next.ptr; /* nothing to undo */ @@ -1992,7 +2006,7 @@ } else { - if (curbuf->b_u_curhead == NULL || p_ul <= 0) + if (curbuf->b_u_curhead == NULL || get_undolevel() <= 0) { beep_flush(); /* nothing to redo */ if (count == startcount - 1) @@ -2750,7 +2764,7 @@ if (im_is_preediting()) return; /* XIM is busy, don't break an undo sequence */ #endif - if (p_ul < 0) + if (get_undolevel() < 0) curbuf->b_u_synced = TRUE; /* no entries, nothing to do */ else { @@ -2910,7 +2924,7 @@ } if (!curbuf->b_u_synced) return; /* already unsynced */ - if (p_ul < 0) + if (get_undolevel() < 0) return; /* no entries, nothing to do */ else { @@ -3107,7 +3121,8 @@ * all the pointers. */ if (uhp == buf->b_u_oldhead) { - u_freeheader(buf, uhp, uhpp); + while (buf->b_u_oldhead != NULL) + u_freeheader(buf, buf->b_u_oldhead, uhpp); return; } diff -ubBwrN ../../work/vim74/src/version.c ./src/version.c --- ../../work/vim74/src/version.c 2013-08-10 14:29:20.000000000 +0300 +++ ./src/version.c 2014-02-22 19:30:46.000000000 +0300 @@ -60,6 +60,11 @@ static char *(features[]) = { +#ifdef HAVE_ACL + "+acl", +#else + "-acl", +#endif #ifdef AMIGA /* only for Amiga systems */ # ifdef FEAT_ARP "+ARP", @@ -721,6 +726,12 @@ # else "-xpm_w32", # endif +#else +# ifdef HAVE_XPM + "+xpm", +# else + "-xpm", +# endif #endif NULL }; @@ -728,6 +739,368 @@ static int included_patches[] = { /* Add new patch number below this line */ /**/ + 183, +/**/ + 182, +/**/ + 181, +/**/ + 180, +/**/ + 179, +/**/ + 178, +/**/ + 177, +/**/ + 176, +/**/ + 175, +/**/ + 174, +/**/ + 173, +/**/ + 172, +/**/ + 171, +/**/ + 170, +/**/ + 169, +/**/ + 168, +/**/ + 167, +/**/ + 166, +/**/ + 165, +/**/ + 164, +/**/ + 163, +/**/ + 162, +/**/ + 161, +/**/ + 160, +/**/ + 159, +/**/ + 158, +/**/ + 157, +/**/ + 156, +/**/ + 155, +/**/ + 154, +/**/ + 153, +/**/ + 152, +/**/ + 151, +/**/ + 150, +/**/ + 149, +/**/ + 148, +/**/ + 146, +/**/ + 145, +/**/ + 144, +/**/ + 143, +/**/ + 142, +/**/ + 141, +/**/ + 140, +/**/ + 139, +/**/ + 138, +/**/ + 137, +/**/ + 136, +/**/ + 135, +/**/ + 134, +/**/ + 133, +/**/ + 132, +/**/ + 131, +/**/ + 130, +/**/ + 129, +/**/ + 128, +/**/ + 127, +/**/ + 126, +/**/ + 125, +/**/ + 124, +/**/ + 123, +/**/ + 122, +/**/ + 121, +/**/ + 120, +/**/ + 119, +/**/ + 118, +/**/ + 117, +/**/ + 116, +/**/ + 115, +/**/ + 114, +/**/ + 113, +/**/ + 112, +/**/ + 111, +/**/ + 110, +/**/ + 109, +/**/ + 108, +/**/ + 107, +/**/ + 106, +/**/ + 105, +/**/ + 104, +/**/ + 103, +/**/ + 102, +/**/ + 101, +/**/ + 100, +/**/ + 99, +/**/ + 98, +/**/ + 97, +/**/ + 96, +/**/ + 95, +/**/ + 94, +/**/ + 93, +/**/ + 92, +/**/ + 91, +/**/ + 90, +/**/ + 89, +/**/ + 88, +/**/ + 87, +/**/ + 86, +/**/ + 85, +/**/ + 84, +/**/ + 83, +/**/ + 82, +/**/ + 81, +/**/ + 80, +/**/ + 79, +/**/ + 78, +/**/ + 77, +/**/ + 76, +/**/ + 75, +/**/ + 74, +/**/ + 73, +/**/ + 72, +/**/ + 71, +/**/ + 70, +/**/ + 69, +/**/ + 68, +/**/ + 67, +/**/ + 66, +/**/ + 65, +/**/ + 63, +/**/ + 62, +/**/ + 61, +/**/ + 60, +/**/ + 59, +/**/ + 58, +/**/ + 57, +/**/ + 56, +/**/ + 55, +/**/ + 54, +/**/ + 53, +/**/ + 52, +/**/ + 51, +/**/ + 50, +/**/ + 49, +/**/ + 48, +/**/ + 47, +/**/ + 46, +/**/ + 45, +/**/ + 44, +/**/ + 43, +/**/ + 42, +/**/ + 41, +/**/ + 40, +/**/ + 39, +/**/ + 38, +/**/ + 37, +/**/ + 36, +/**/ + 35, +/**/ + 34, +/**/ + 33, +/**/ + 32, +/**/ + 31, +/**/ + 30, +/**/ + 29, +/**/ + 28, +/**/ + 27, +/**/ + 26, +/**/ + 25, +/**/ + 24, +/**/ + 23, +/**/ + 22, +/**/ + 21, +/**/ + 20, +/**/ + 19, +/**/ + 18, +/**/ + 17, +/**/ + 16, +/**/ + 15, +/**/ + 14, +/**/ + 13, +/**/ + 12, +/**/ + 11, +/**/ + 10, +/**/ + 9, +/**/ + 8, +/**/ + 7, +/**/ + 6, +/**/ + 5, +/**/ + 4, +/**/ + 3, +/**/ + 2, +/**/ + 1, +/**/ 0 }; diff -ubBwrN ../../work/vim74/src/vim.h ./src/vim.h --- ../../work/vim74/src/vim.h 2013-08-02 17:02:27.000000000 +0300 +++ ./src/vim.h 2014-02-22 19:30:45.000000000 +0300 @@ -1176,6 +1176,15 @@ #define RESIZE_BOTH 15 /* resize in both directions */ /* + * flags for check_changed() + */ +#define CCGD_AW 1 /* do autowrite if buffer was changed */ +#define CCGD_MULTWIN 2 /* check also when several wins for the buf */ +#define CCGD_FORCEIT 4 /* ! used */ +#define CCGD_ALLBUF 8 /* may write all buffers */ +#define CCGD_EXCMD 16 /* may suggest using ! */ + +/* * "flags" values for option-setting functions. * When OPT_GLOBAL and OPT_LOCAL are both missing, set both local and global * values, get local value. @@ -1864,9 +1873,10 @@ #define VV_MOUSE_COL 51 #define VV_OP 52 #define VV_SEARCHFORWARD 53 -#define VV_OLDFILES 54 -#define VV_WINDOWID 55 -#define VV_LEN 56 /* number of v: vars */ +#define VV_HLSEARCH 54 +#define VV_OLDFILES 55 +#define VV_WINDOWID 56 +#define VV_LEN 57 /* number of v: vars */ #ifdef FEAT_CLIPBOARD @@ -2239,6 +2249,7 @@ #define SOPT_BUF 0x20 /* Option has buffer-local value */ #define SOPT_UNSET 0x40 /* Option does not have local value set */ +/* Option types for various functions in option.c */ #define SREQ_GLOBAL 0 /* Request global option */ #define SREQ_WIN 1 /* Request window-local option */ #define SREQ_BUF 2 /* Request buffer-local option */ @@ -2246,4 +2257,10 @@ /* Character used as separated in autoload function/variable names. */ #define AUTOLOAD_CHAR '#' +#ifdef FEAT_EVAL +# define SET_NO_HLSEARCH(flag) no_hlsearch = (flag); set_vim_var_nr(VV_HLSEARCH, !no_hlsearch) +#else +# define SET_NO_HLSEARCH(flag) no_hlsearch = (flag) +#endif + #endif /* VIM__H */ diff -ubBwrN ../../work/vim74/src/window.c ./src/window.c --- ../../work/vim74/src/window.c 2013-07-24 18:38:29.000000000 +0300 +++ ./src/window.c 2014-02-22 19:30:44.000000000 +0300 @@ -1216,8 +1216,8 @@ else copy_loclist(oldp, newp); #endif - if (oldp->w_localdir != NULL) - newp->w_localdir = vim_strsave(oldp->w_localdir); + newp->w_localdir = (oldp->w_localdir == NULL) + ? NULL : vim_strsave(oldp->w_localdir); /* copy tagstack and folds */ for (i = 0; i < oldp->w_tagstacklen; i++) @@ -2172,8 +2172,9 @@ * If "free_buf" is TRUE related buffer may be unloaded. * * Called by :quit, :close, :xit, :wq and findtag(). + * Returns FAIL when the window was not closed. */ - void + int win_close(win, free_buf) win_T *win; int free_buf; @@ -2190,21 +2191,21 @@ if (last_window()) { EMSG(_("E444: Cannot close last window")); - return; + return FAIL; } #ifdef FEAT_AUTOCMD if (win->w_closing || (win->w_buffer != NULL && win->w_buffer->b_closing)) - return; /* window is already being closed */ + return FAIL; /* window is already being closed */ if (win == aucmd_win) { EMSG(_("E813: Cannot close autocmd window")); - return; + return FAIL; } if ((firstwin == aucmd_win || lastwin == aucmd_win) && one_window()) { EMSG(_("E814: Cannot close window, only autocmd window would remain")); - return; + return FAIL; } #endif @@ -2212,7 +2213,7 @@ * and then close the window and the tab page to avoid that curwin and * curtab are invalid while we are freeing memory. */ if (close_last_window_tabpage(win, free_buf, prev_curtab)) - return; + return FAIL; /* When closing the help window, try restoring a snapshot after closing * the window. Otherwise clear the snapshot, it's now invalid. */ @@ -2240,22 +2241,22 @@ win->w_closing = TRUE; apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); if (!win_valid(win)) - return; + return FAIL; win->w_closing = FALSE; if (last_window()) - return; + return FAIL; } win->w_closing = TRUE; apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf); if (!win_valid(win)) - return; + return FAIL; win->w_closing = FALSE; if (last_window()) - return; + return FAIL; # ifdef FEAT_EVAL /* autocmds may abort script processing */ if (aborting()) - return; + return FAIL; # endif } #endif @@ -2303,7 +2304,7 @@ * other window or moved to another tab page. */ else if (!win_valid(win) || last_window() || curtab != prev_curtab || close_last_window_tabpage(win, free_buf, prev_curtab)) - return; + return FAIL; /* Free the memory used for the window and get the window that received * the screen space. */ @@ -2383,6 +2384,7 @@ #endif redraw_all_later(NOT_VALID); + return OK; } /* diff -ubBwrN ../../work/vim74/src/xxd/Make_cyg.mak ./src/xxd/Make_cyg.mak --- ../../work/vim74/src/xxd/Make_cyg.mak 2010-05-15 14:04:06.000000000 +0300 +++ ./src/xxd/Make_cyg.mak 2014-02-22 19:30:40.000000000 +0300 @@ -8,7 +8,7 @@ DEFINES = LIBS = -lc else -DEFINES = -mno-cygwin +DEFINES = LIBS = endif diff -ubBwrN ../../work/vim74/test100.in ./test100.in --- ../../work/vim74/test100.in 1970-01-01 03:00:00.000000000 +0300 +++ ./test100.in 2014-02-22 19:30:42.000000000 +0300 @@ -0,0 +1,42 @@ +Tests for 'undolevel' setting being global-local + +STARTTEST +:so small.vim +:set nocompatible viminfo+=nviminfo ul=5 +:fu! FillBuffer() + :for i in range(1,13) + :put=i + :exe "setg ul=" . &g:ul + :endfor +:endfu +:fu! UndoLevel() + :redir @a | setglobal undolevels? | echon ' global' | setlocal undolevels? | echon ' local' |redir end + :$put a +:endfu +:new one +:0put ='ONE: expecting global undolevels: 5, local undolevels: -123456 (default)' +:call FillBuffer() +:call feedkeys(":earlier 10\n", 't') +:call UndoLevel() +:%w! test.out +:new two +:0put ='TWO: expecting global undolevels: 5, local undolevels: 2 (first) then 10 (afterwards)' +:setlocal ul=2 +:call FillBuffer() +:call feedkeys(":earlier 10\n", 't') +:call UndoLevel() +:setlocal ul=10 +:call UndoLevel() +:%w >> test.out +:wincmd p +:redir >>test.out | echo "global value shouldn't be changed and still be 5!" | echo 'ONE: expecting global undolevels: 5, local undolevels: -123456 (default)'|:setglobal undolevels? | echon ' global' | setlocal undolevels? | echon ' local' |echo "" |redir end +:new three +:setglobal ul=50 +:1put ='global value should be changed to 50' +:2put ='THREE: expecting global undolevels: 50, local undolevels: -123456 (default)' +:call UndoLevel() +:%w >> test.out +:"sleep 10 +:qa! +ENDTEST + diff -ubBwrN ../../work/vim74/test100.ok ./test100.ok --- ../../work/vim74/test100.ok 1970-01-01 03:00:00.000000000 +0300 +++ ./test100.ok 2014-02-22 19:30:42.000000000 +0300 @@ -0,0 +1,41 @@ +ONE: expecting global undolevels: 5, local undolevels: -123456 (default) +1 +2 +3 +4 +5 +6 +7 + + + undolevels=5 global + undolevels=-123456 local +TWO: expecting global undolevels: 5, local undolevels: 2 (first) then 10 (afterwards) +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 + + + undolevels=5 global + undolevels=2 local + + undolevels=5 global + undolevels=10 local + +global value shouldn't be changed and still be 5! +ONE: expecting global undolevels: 5, local undolevels: -123456 (default) + undolevels=5 global + undolevels=-123456 local + +global value should be changed to 50 +THREE: expecting global undolevels: 50, local undolevels: -123456 (default) + + undolevels=50 global + undolevels=-123456 local diff -ubBwrN ../../work/vim74/test101.in ./test101.in --- ../../work/vim74/test101.in 1970-01-01 03:00:00.000000000 +0300 +++ ./test101.in 2014-02-22 19:30:42.000000000 +0300 @@ -0,0 +1,45 @@ +Test for v:hlsearch vim: set ft=vim : + +STARTTEST +:" Last abc: Q +:so small.vim +:new +:call setline(1, repeat(['aaa'], 10)) +:set hlsearch nolazyredraw +:let r=[] +:command -nargs=0 -bar AddR :call add(r, [screenattr(1, 1), v:hlsearch]) +/aaa +:AddR +:nohlsearch +:AddR +:let v:hlsearch=1 +:AddR +:let v:hlsearch=0 +:AddR +:set hlsearch +:AddR +:let v:hlsearch=0 +:AddR +n:AddR +:let v:hlsearch=0 +:AddR +/ +:AddR +:let r1=r[0][0] +:" I guess it is not guaranteed that screenattr outputs always the same character +:call map(r, 'v:val[1].":".(v:val[0]==r1?"highlighted":"not highlighted")') +:try +: let v:hlsearch=[] +:catch +: call add(r, matchstr(v:exception,'^Vim(let):E\d\+:')) +:endtry +:bwipeout! +:$put=r +:call garbagecollect(1) +:" +:/^start:/,$wq! test.out +:" vim: et ts=4 isk-=\: +:call getchar() +ENDTEST + +start: diff -ubBwrN ../../work/vim74/test101.ok ./test101.ok --- ../../work/vim74/test101.ok 1970-01-01 03:00:00.000000000 +0300 +++ ./test101.ok 2014-02-22 19:30:42.000000000 +0300 @@ -0,0 +1,11 @@ +start: +1:highlighted +0:not highlighted +1:highlighted +0:not highlighted +1:highlighted +0:not highlighted +1:highlighted +0:not highlighted +1:highlighted +Vim(let):E706: diff -ubBwrN ../../work/vim74/test102.in ./test102.in --- ../../work/vim74/test102.in 1970-01-01 03:00:00.000000000 +0300 +++ ./test102.in 2014-02-22 19:30:43.000000000 +0300 @@ -0,0 +1,12 @@ +Test if fnameescape is correct for special chars like ! + +STARTTEST +:%d +:let fname = 'Xspa ce' +:try | exe "w! " . fnameescape(fname) | put='Space' | endtry +:let fname = 'Xemark!' +:try | exe "w! " . fnameescape(fname) | put='ExclamationMark' | endtry +:w! test.out +:qa! +ENDTEST + diff -ubBwrN ../../work/vim74/test102.ok ./test102.ok --- ../../work/vim74/test102.ok 1970-01-01 03:00:00.000000000 +0300 +++ ./test102.ok 2014-02-22 19:30:43.000000000 +0300 @@ -0,0 +1,3 @@ + +Space +ExclamationMark diff -ubBwrN ../../work/vim74/test103.in ./test103.in --- ../../work/vim74/test103.in 1970-01-01 03:00:00.000000000 +0300 +++ ./test103.in 2014-02-22 19:30:43.000000000 +0300 @@ -0,0 +1,37 @@ +Test for visual mode not being reset causing E315 error. +STARTTEST +:so small.vim +:enew +:let g:msg="Everything's fine." +:function! TriggerTheProblem() +: " At this point there is no visual selection because :call reset it. +: " Let's restore the selection: +: normal gv +: '<,'>del _ +: try +: exe "normal \" +: catch /^Vim\%((\a\+)\)\=:E315/ +: echom 'Snap! E315 error!' +: let g:msg='Snap! E315 error!' +: endtry +:endfunction +:enew +:setl buftype=nofile +:call append(line('$'), 'Delete this line.') +:" +:" +:" NOTE: this has to be done by a call to a function because executing :del the +:" ex-way will require the colon operator which resets the visual mode thus +:" preventing the problem: +:" +GV:call TriggerTheProblem() +:%del _ +:call append(line('$'), g:msg) +:w! test.out +:brewind +ENDTEST + +STARTTEST +:qa! +ENDTEST + diff -ubBwrN ../../work/vim74/test103.ok ./test103.ok --- ../../work/vim74/test103.ok 1970-01-01 03:00:00.000000000 +0300 +++ ./test103.ok 2014-02-22 19:30:43.000000000 +0300 @@ -0,0 +1,2 @@ + +Everything's fine. diff -ubBwrN ../../work/vim74/test104.in ./test104.in --- ../../work/vim74/test104.in 1970-01-01 03:00:00.000000000 +0300 +++ ./test104.in 2014-02-22 19:30:45.000000000 +0300 @@ -0,0 +1,16 @@ +Tests for autoload. vim: set ft=vim ts=8 : + +STARTTEST +:so small.vim +:set runtimepath+=./sautest +:" Test to not autoload when assigning. It causes internal error. +:try +: let Test104#numvar = function('tr') +: $put ='OK: ' . string(Test104#numvar) +:catch +: $put ='FAIL: ' . v:exception +:endtry +:/^Results/,$wq! test.out +ENDTEST + +Results of test104: diff -ubBwrN ../../work/vim74/test104.ok ./test104.ok --- ../../work/vim74/test104.ok 1970-01-01 03:00:00.000000000 +0300 +++ ./test104.ok 2014-02-22 19:30:45.000000000 +0300 @@ -0,0 +1,2 @@ +Results of test104: +OK: function('tr') diff -ubBwrN ../../work/vim74/test99.in ./test99.in --- ../../work/vim74/test99.in 1970-01-01 03:00:00.000000000 +0300 +++ ./test99.in 2014-02-22 19:30:40.000000000 +0300 @@ -0,0 +1,68 @@ +Tests for regexp with multi-byte encoding and various magic settings. +Test matchstr() with a count and multi-byte chars. +See test44 for exactly the same test with re=1. + +STARTTEST +:so mbyte.vim +:set nocompatible encoding=utf-8 termencoding=latin1 viminfo+=nviminfo +:set re=2 +/^1 +/a*b\{2}c\+/e +x/\Md\*e\{2}f\+/e +x:set nomagic +/g\*h\{2}i\+/e +x/\mj*k\{2}l\+/e +x/\vm*n{2}o+/e +x/\V^aa$ +x:set magic +/\v(a)(b)\2\1\1/e +x/\V[ab]\(\[xy]\)\1 +x:" Now search for multi-byte without composing char +/ม +x:" Now search for multi-byte with composing char +/ม่ +x:" find word by change of word class +/ち\<カヨ\>は +x:" Test \%u, [\u] and friends +/\%u20ac +x/[\u4f7f\u5929]\+ +x/\%U12345678 +x/[\U1234abcd\u1234\uabcd] +x/\%d21879b +x/ [[=A=]]* [[=B=]]* [[=C=]]* [[=D=]]* [[=E=]]* [[=F=]]* [[=G=]]* [[=H=]]* [[=I=]]* [[=J=]]* [[=K=]]* [[=L=]]* [[=M=]]* [[=N=]]* [[=O=]]* [[=P=]]* [[=Q=]]* [[=R=]]* [[=S=]]* [[=T=]]* [[=U=]]* [[=V=]]* [[=W=]]* [[=X=]]* [[=Y=]]* [[=Z=]]*/e +x/ [[=a=]]* [[=b=]]* [[=c=]]* [[=d=]]* [[=e=]]* [[=f=]]* [[=g=]]* [[=h=]]* [[=i=]]* [[=j=]]* [[=k=]]* [[=l=]]* [[=m=]]* [[=n=]]* [[=o=]]* [[=p=]]* [[=q=]]* [[=r=]]* [[=s=]]* [[=t=]]* [[=u=]]* [[=v=]]* [[=w=]]* [[=x=]]* [[=y=]]* [[=z=]]*/e +x:" Test backwards search from a multi-byte char +/x +x?. +x:let @w=':%s#comb[i]nations#œ̄ṣ́m̥̄ᾱ̆́#g' +:@w +:?^1?,$w! test.out +:e! test.out +G:put =matchstr(\"אבגד\", \".\", 0, 2) " ב +:put =matchstr(\"אבגד\", \"..\", 0, 2) " בג +:put =matchstr(\"אבגד\", \".\", 0, 0) " א +:put =matchstr(\"אבגד\", \".\", 4, -1) " ג +:w! +:qa! +ENDTEST + +1 a aa abb abbccc +2 d dd dee deefff +3 g gg ghh ghhiii +4 j jj jkk jkklll +5 m mm mnn mnnooo +6 x ^aa$ x +7 (a)(b) abbaa +8 axx [ab]xx +9 หม่x อมx +a อมx หม่x +b ちカヨは +c x ¬€x +d 天使x +e y +f z +g a啷bb +h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐẔ +i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑẕ +j 0123❤x +k combinations diff -ubBwrN ../../work/vim74/test99.ok ./test99.ok --- ../../work/vim74/test99.ok 1970-01-01 03:00:00.000000000 +0300 +++ ./test99.ok 2014-02-22 19:30:40.000000000 +0300 @@ -0,0 +1,24 @@ +1 a aa abb abbcc +2 d dd dee deeff +3 g gg ghh ghhii +4 j jj jkk jkkll +5 m mm mnn mnnoo +6 x aa$ x +7 (a)(b) abba +8 axx ab]xx +9 หม่x อx +a อมx หx +b カヨは +c x ¬x +d 使x +e y +f z +g abb +h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐ +i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑ +j 012❤ +k œ̄ṣ́m̥̄ᾱ̆́ +ב +בג +א +ג