Submitted By: Jim Gifford (jim at cross-lfs dot org) Date: 03-22-2009 Initial Package Version: 7.2 Origin: Upstream Upstream Status: Applied Description: Contains all upstream patches up to 7.2.148 The following patches were skipped 007 036 041 049 071 072 074 088 089 093 101 138 diff -Naur vim72.orig/Filelist vim72/Filelist --- vim72.orig/Filelist 2008-07-06 11:02:23.000000000 -0700 +++ vim72/Filelist 2009-03-22 21:27:50.249298785 -0700 @@ -285,6 +285,7 @@ src/proto/os_win32.pro \ src/proto/os_mswin.pro \ src/testdir/Make_dos.mak \ + src/testdir/Make_ming.mak \ src/testdir/dos.vim \ src/uninstal.c \ src/vim.def \ diff -Naur vim72.orig/runtime/doc/cmdline.txt vim72/runtime/doc/cmdline.txt --- vim72.orig/runtime/doc/cmdline.txt 2008-08-09 07:22:59.000000000 -0700 +++ vim72/runtime/doc/cmdline.txt 2009-03-22 21:28:12.878748987 -0700 @@ -1,4 +1,4 @@ -*cmdline.txt* For Vim version 7.2. Last change: 2008 Jul 29 +*cmdline.txt* For Vim version 7.2. Last change: 2008 Sep 18 VIM REFERENCE MANUAL by Bram Moolenaar @@ -157,6 +157,11 @@ (doesn't work at the expression prompt; some things such as changing the buffer or current window are not allowed to avoid side effects) + When the result is a |List| the items are used + as lines. They can have line breaks inside + too. + When the result is a Float it's automatically + converted to a String. See |registers| about registers. {not in Vi} Implementation detail: When using the |expression| register and invoking setcmdpos(), this sets the position before @@ -730,19 +735,29 @@ In Ex commands, at places where a file name can be used, the following characters have a special meaning. These can also be used in the expression function expand() |expand()|. - % is replaced with the current file name *:_%* - # is replaced with the alternate file name *:_#* + % Is replaced with the current file name. *:_%* *c_%* + # Is replaced with the alternate file name. *:_#* *c_#* #n (where n is a number) is replaced with the file name of - buffer n. "#0" is the same as "#" - ## is replaced with all names in the argument list *:_##* + buffer n. "#0" is the same as "#". + ## Is replaced with all names in the argument list *:_##* *c_##* concatenated, separated by spaces. Each space in a name is preceded with a backslash. -Note that these give the file name as it was typed. If an absolute path is -needed (when using the file name from a different directory), you need to add -":p". See |filename-modifiers|. + # 0) is replaced with old *:_#<* *c_#<* + file name n. See |:oldfiles| or |v:oldfiles| to get the + number. *E809* + {only when compiled with the +eval and +viminfo features} + +Note that these, except "# +commands. For those you probably have to use quotes (this fails for files +that contain a quote and wildcards): > :!ls "%" :r !spell "%" diff -Naur vim72.orig/runtime/doc/eval.txt vim72/runtime/doc/eval.txt --- vim72.orig/runtime/doc/eval.txt 2008-08-09 07:22:59.000000000 -0700 +++ vim72/runtime/doc/eval.txt 2009-03-22 21:29:41.424424361 -0700 @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 7.2. Last change: 2008 Aug 09 +*eval.txt* For Vim version 7.2. Last change: 2008 Nov 27 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1484,6 +1484,17 @@ This is the screen column number, like with |virtcol()|. The value is zero when there was no mouse button click. + *v:oldfiles* *oldfiles-variable* +v:oldfiles List of file names that is loaded from the |viminfo| file on + startup. These are the files that Vim remembers marks for. + The length of the List is limited by the ' argument of the + 'viminfo' option (default is 100). + Also see |:oldfiles| and |c_#<|. + The List can be modified, but this has no effect on what is + stored in the |viminfo| file later. If you use values other + than String this will cause trouble. + {only when compiled with the +viminfo feature} + *v:operator* *operator-variable* v:operator The last operator given in Normal mode. This is a single character except for commands starting with or , @@ -1695,7 +1706,7 @@ exists( {expr}) Number TRUE if {expr} exists extend({expr1}, {expr2} [, {expr3}]) List/Dict insert items of {expr2} into {expr1} -expand( {expr}) String expand special keywords in {expr} +expand( {expr} [, {flag}]) String expand special keywords in {expr} feedkeys( {string} [, {mode}]) Number add key sequence to typeahead buffer filereadable( {file}) Number TRUE if {file} is a readable file filewritable( {file}) Number TRUE if {file} is a writable file @@ -1747,8 +1758,9 @@ getwinposx() Number X coord in pixels of GUI Vim window getwinposy() Number Y coord in pixels of GUI Vim window getwinvar( {nr}, {varname}) any variable {varname} in window {nr} -glob( {expr}) String expand file wildcards in {expr} -globpath( {path}, {expr}) String do glob({expr}) for all dirs in {path} +glob( {expr} [, {flag}]) String expand file wildcards in {expr} +globpath( {path}, {expr} [, {flag}]) + String do glob({expr}) for all dirs in {path} has( {feature}) Number TRUE if feature {feature} supported has_key( {dict}, {key}) Number TRUE if {dict} has entry {key} haslocaldir() Number TRUE if current window executed |:lcd| @@ -3275,14 +3287,16 @@ :let list_is_on = getwinvar(2, '&list') :echo "myvar = " . getwinvar(1, 'myvar') < - *glob()* -glob({expr}) Expand the file wildcards in {expr}. See |wildcards| for the +glob({expr} [, {flag}]) *glob()* + Expand the file wildcards in {expr}. See |wildcards| for the use of special characters. The result is a String. When there are several matches, they are separated by characters. - The 'wildignore' option applies: Names matching one of the - patterns in 'wildignore' will be skipped. + Unless the optional {flag} argument is given and is non-zero, + the 'suffixes' and 'wildignore' options apply: Names matching + one of the patterns in 'wildignore' will be skipped and + 'suffixes' affect the ordering of matches. If the expansion fails, the result is an empty string. A name for a non-existing file is not included. @@ -3296,20 +3310,22 @@ See |expand()| for expanding special Vim variables. See |system()| for getting the raw output of an external command. -globpath({path}, {expr}) *globpath()* +globpath({path}, {expr} [, {flag}]) *globpath()* Perform glob() on all directories in {path} and concatenate the results. Example: > :echo globpath(&rtp, "syntax/c.vim") < {path} is a comma-separated list of directory names. Each directory name is prepended to {expr} and expanded like with - glob(). A path separator is inserted when needed. + |glob()|. A path separator is inserted when needed. To add a comma inside a directory name escape it with a backslash. Note that on MS-Windows a directory may have a trailing backslash, remove it if you put a comma after it. If the expansion fails for one of the directories, there is no error message. - The 'wildignore' option applies: Names matching one of the - patterns in 'wildignore' will be skipped. + Unless the optional {flag} argument is given and is non-zero, + the 'suffixes' and 'wildignore' options apply: Names matching + one of the patterns in 'wildignore' will be skipped and + 'suffixes' affect the ordering of matches. The "**" item can be used to search in a directory tree. For example, to find all "README.txt" files in the directories @@ -5332,10 +5348,12 @@ "fg" foreground color (GUI: color name used to set the color, cterm: color number as a string, term: empty string) - "bg" background color (like "fg") + "bg" background color (as with "fg") + "sp" special color (as with "fg") |highlight-guisp| "fg#" like "fg", but for the GUI and the GUI is running the name in "#RRGGBB" form "bg#" like "fg#" for "bg" + "sp#" like "fg#" for "sp" "bold" "1" if bold "italic" "1" if italic "reverse" "1" if reverse @@ -5823,7 +5841,8 @@ mouse_pterm Compiled with support for qnx pterm mouse. mouse_sysmouse Compiled with support for sysmouse (*BSD console mouse) mouse_xterm Compiled with support for xterm mouse. -multi_byte Compiled with support for editing Korean et al. +multi_byte Compiled with support for 'encoding' +multi_byte_encoding 'encoding' is set to a multi-byte encoding. multi_byte_ime Compiled with support for IME input method. multi_lang Compiled with support for multiple languages. mzscheme Compiled with MzScheme interface |mzscheme|. diff -Naur vim72.orig/runtime/doc/if_cscop.txt vim72/runtime/doc/if_cscop.txt --- vim72.orig/runtime/doc/if_cscop.txt 2008-08-09 07:22:59.000000000 -0700 +++ vim72/runtime/doc/if_cscop.txt 2009-03-22 21:32:56.384915491 -0700 @@ -1,4 +1,4 @@ -*if_cscop.txt* For Vim version 7.2. Last change: 2005 Mar 29 +*if_cscop.txt* For Vim version 7.2. Last change: 2009 Mar 18 VIM REFERENCE MANUAL by Andy Kahn @@ -131,11 +131,22 @@ 7 or f: Find this file 8 or i: Find files #including this file + For all types, except 4 and 6, leading white space for {name} is + removed. For 4 and 6 there is exactly one space between {querytype} + and {name}. Further white space is included in {name}. + EXAMPLES > :cscope find c vim_free - :cscope find 3 vim_free + :cscope find 3 vim_free +< + These two examples perform the same query: functions calling + "vim_free". > + + :cscope find t initOnce + :cscope find t initOnce < - These two examples perform the same query. > + The first one searches for the text "initOnce", the second one for + " initOnce". > :cscope find 0 DEFAULT_TERM < diff -Naur vim72.orig/runtime/doc/netbeans.txt vim72/runtime/doc/netbeans.txt --- vim72.orig/runtime/doc/netbeans.txt 2008-08-09 07:22:59.000000000 -0700 +++ vim72/runtime/doc/netbeans.txt 2009-03-22 21:30:13.574484705 -0700 @@ -1,4 +1,4 @@ -*netbeans.txt* For Vim version 7.2. Last change: 2008 Jun 28 +*netbeans.txt* For Vim version 7.2. Last change: 2009 Jan 06 VIM REFERENCE MANUAL by Gordon Prieur et al. @@ -722,8 +722,10 @@ of the cursor. New in version 2.1. -killed A file was closed by the user. Only for files that have been - assigned a number by the IDE. +killed A file was deleted or wiped out by the user and the buffer + annotations have been removed. The bufID number for this + buffer has become invalid. Only for files that have been + assigned a bufID number by the IDE. newDotAndMark off off Reports the position of the cursor being at "off" bytes into diff -Naur vim72.orig/runtime/doc/options.txt vim72/runtime/doc/options.txt --- vim72.orig/runtime/doc/options.txt 2008-08-09 07:22:59.000000000 -0700 +++ vim72/runtime/doc/options.txt 2009-03-22 21:31:27.231204917 -0700 @@ -1,4 +1,4 @@ -*options.txt* For Vim version 7.2. Last change: 2008 Aug 06 +*options.txt* For Vim version 7.2. Last change: 2008 Nov 25 VIM REFERENCE MANUAL by Bram Moolenaar @@ -4175,9 +4175,6 @@ be able to execute Normal mode commands. This is the opposite of the 'keymap' option, where characters are mapped in Insert mode. - This only works for 8-bit characters. The value of 'langmap' may be - specified with multi-byte characters (e.g., UTF-8), but only the lower - 8 bits of each character will be used. Example (for Greek, in UTF-8): *greek* > :set langmap=ΑA,ΒB,ΨC,ΔD,ΕE,ΦF,ΓG,ΗH,ΙI,ΞJ,ΚK,ΛL,ΜM,ΝN,ΟO,ΠP,QQ,ΡR,ΣS,ΤT,ΘU,ΩV,WW,ΧX,ΥY,ΖZ,αa,βb,ψc,δd,εe,φf,γg,ηh,ιi,ξj,κk,λl,μm,νn,οo,πp,qq,ρr,σs,τt,θu,ωv,ςw,χx,υy,ζz @@ -7472,7 +7469,9 @@ {not available when compiled without the |+wildignore| feature} A list of file patterns. A file that matches with one of these - patterns is ignored when completing file or directory names. + patterns is ignored when completing file or directory names, and + influences the result of |expand()|, |glob()| and |globpath()| unless + a flag is passed to disable this. The pattern is used like with |:autocmd|, see |autocmd-patterns|. Also see 'suffixes'. Example: > diff -Naur vim72.orig/runtime/doc/spell.txt vim72/runtime/doc/spell.txt --- vim72.orig/runtime/doc/spell.txt 2008-08-09 07:23:00.000000000 -0700 +++ vim72/runtime/doc/spell.txt 2009-03-22 21:29:26.755482609 -0700 @@ -1,4 +1,4 @@ -*spell.txt* For Vim version 7.2. Last change: 2008 Jun 21 +*spell.txt* For Vim version 7.2. Last change: 2008 Nov 30 VIM REFERENCE MANUAL by Bram Moolenaar @@ -831,8 +831,11 @@ # comment line ~ -With some items it's also possible to put a comment after it, but this isn't -supported in general. +Items with a fixed number of arguments can be followed by a comment. But only +if none of the arguments can contain white space. The comment must start with +a "#" character. Example: + + KEEPCASE = # fix case for words with this flag ~ ENCODING *spell-SET* @@ -965,6 +968,9 @@ Note: When using utf-8 only characters up to 65000 may be used for flags. +Note: even when using "num" or "long" the number of flags available to +compounding and prefixes is limited to about 250. + AFFIXES *spell-PFX* *spell-SFX* @@ -1178,6 +1184,9 @@ The flag also applies to the word with affixes, thus this can be used to mark a whole bunch of related words as bad. + *spell-FORBIDDENWORD* +FORBIDDENWORD can be used just like BAD. For compatibility with Hunspell. + *spell-NEEDAFFIX* The NEEDAFFIX flag is used to require that a word is used with an affix. The word itself is not a good word (unless there is an empty affix). Example: @@ -1268,6 +1277,10 @@ NEEDCOMPOUND & ~ + *spell-ONLYINCOMPOUND* +The ONLYINCOMPOUND does exactly the same as NEEDCOMPOUND. Supported for +compatiblity with Hunspell. + *spell-COMPOUNDMIN* The minimal character length of a word used for compounding is specified with COMPOUNDMIN. Example: @@ -1328,6 +1341,20 @@ rules. Can also be used for an affix to count the affix as a compounding word. + *spell-CHECKCOMPOUNDPATTERN* +CHECKCOMPOUNDPATTERN is used to define patterns that, when matching at the +position where two words are compounded together forbids the compound. +For example: + CHECKCOMPOUNDPATTERN o e ~ + +This forbids compounding if the first word ends in "o" and the second word +starts with "e". + +The arguments must be plain text, no patterns are actually supported, despite +the item name. Case is always ignored. + +The Hunspell feature to use three arguments and flags is not supported. + *spell-SYLLABLE* The SYLLABLE item defines characters or character sequences that are used to count the number of syllables in a word. Example: @@ -1496,6 +1523,10 @@ ACCENT (Hunspell) *spell-ACCENT* Use MAP instead. |spell-MAP| +BREAK (Hunspell) *spell-BREAK* + Define break points. Unclear how it works exactly. + Not supported. + CHECKCOMPOUNDCASE (Hunspell) *spell-CHECKCOMPOUNDCASE* Disallow uppercase letters at compound word boundaries. Not supported. @@ -1512,9 +1543,6 @@ Forbid three identical characters when compounding. Not supported. -CHECKCOMPOUNDPATTERN (Hunspell) *spell-CHECKCOMPOUNDPATTERN* - Forbid compounding when patterns match. Not supported. - COMPLEXPREFIXES (Hunspell) *spell-COMPLEXPREFIXES* Enables using two prefixes. Not supported. @@ -1536,13 +1564,18 @@ COMPOUNDMIDDLE (Hunspell) *spell-COMPOUNDMIDDLE* Use COMPOUNDRULE instead. |spell-COMPOUNDRULE| +COMPOUNDRULES (Hunspell) *spell-COMPOUNDRULES* + Number of COMPOUNDRULE lines following. Ignored, but the + argument must be a number. + COMPOUNDSYLLABLE (Hunspell) *spell-COMPOUNDSYLLABLE* Use SYLLABLE and COMPOUNDSYLMAX instead. |spell-SYLLABLE| |spell-COMPOUNDSYLMAX| -FORBIDDENWORD (Hunspell) *spell-FORBIDDENWORD* - Use BAD instead. |spell-BAD| - +KEY (Hunspell) *spell-KEY* + Define characters that are close together on the keyboard. + Used to give better suggestions. Not supported. + LANG (Hunspell) *spell-LANG* This specifies language-specific behavior. This actually moves part of the language knowledge into the program, @@ -1553,10 +1586,7 @@ Only needed for morphological analysis. MAXNGRAMSUGS (Hunspell) *spell-MAXNGRAMSUGS* - Not supported. - -ONLYINCOMPOUND (Hunspell) *spell-ONLYINCOMPOUND* - Use NEEDCOMPOUND instead. |spell-NEEDCOMPOUND| + Set number of n-gram suggestions. Not supported. PSEUDOROOT (Hunspell) *spell-PSEUDOROOT* Use NEEDAFFIX instead. |spell-NEEDAFFIX| diff -Naur vim72.orig/runtime/doc/starting.txt vim72/runtime/doc/starting.txt --- vim72.orig/runtime/doc/starting.txt 2008-08-09 07:23:00.000000000 -0700 +++ vim72/runtime/doc/starting.txt 2009-03-22 21:28:12.882751502 -0700 @@ -1,4 +1,4 @@ -*starting.txt* For Vim version 7.2. Last change: 2008 Jun 21 +*starting.txt* For Vim version 7.2. Last change: 2008 Nov 09 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1337,8 +1337,9 @@ *viminfo-read* When Vim is started and the 'viminfo' option is non-empty, the contents of the viminfo file are read and the info can be used in the appropriate places. -The marks are not read in at startup (but file marks are). See -|initialization| for how to set the 'viminfo' option upon startup. +The |v:oldfiles| variable is filled. The marks are not read in at startup +(but file marks are). See |initialization| for how to set the 'viminfo' +option upon startup. *viminfo-write* When Vim exits and 'viminfo' is non-empty, the info is stored in the viminfo @@ -1372,6 +1373,8 @@ that start with any string given with the "r" flag in 'viminfo'. This can be used to avoid saving marks for files on removable media (for MS-DOS you would use "ra:,rb:", for Amiga "rdf0:,rdf1:,rdf2:"). +The |v:oldfiles| variable is filled with the file names that the viminfo file +has marks for. *viminfo-file-marks* Uppercase marks ('A to 'Z) are stored when writing the viminfo file. The @@ -1463,8 +1466,8 @@ *:rv* *:rviminfo* *E195* :rv[iminfo][!] [file] Read from viminfo file [file] (default: see above). If [!] is given, then any information that is - already set (registers, marks, etc.) will be - overwritten. {not in Vi} + already set (registers, marks, |v:oldfiles|, etc.) + will be overwritten {not in Vi} *:wv* *:wviminfo* *E137* *E138* *E574* :wv[iminfo][!] [file] Write to viminfo file [file] (default: see above). @@ -1479,4 +1482,20 @@ the .viminfo file. {not in Vi} + *:ol* *:oldfiles* +:ol[dfiles] List the files that have marks stored in the viminfo + file. This list is read on startup and only changes + afterwards with ":rviminfo!". Also see |v:oldfiles|. + The number can be used with |c_#<|. + {not in Vi, only when compiled with the +eval feature} + +:bro[wse] ol[dfiles][!] + List file names as with |:oldfiles|, and then prompt + for a number. When the number is valid that file from + the list is edited. + If you get the |press-enter| prompt you can press "q" + and still get the prompt to enter a file number. + Use ! to abondon a modified buffer. |abandon| + {not when compiled with tiny or small features} + vim:tw=78:ts=8:ft=help:norl: diff -Naur vim72.orig/runtime/doc/usr_21.txt vim72/runtime/doc/usr_21.txt --- vim72.orig/runtime/doc/usr_21.txt 2008-08-09 07:23:01.000000000 -0700 +++ vim72/runtime/doc/usr_21.txt 2009-03-22 21:28:12.882751502 -0700 @@ -1,4 +1,4 @@ -*usr_21.txt* For Vim version 7.2. Last change: 2007 May 01 +*usr_21.txt* For Vim version 7.2. Last change: 2008 Nov 09 VIM USER MANUAL - by Bram Moolenaar @@ -153,7 +153,7 @@ to be lost. Each item can be remembered only once. -GETTING BACK TO WHERE YOU WERE +GETTING BACK TO WHERE YOU STOPPED VIM You are halfway editing a file and it's time to leave for holidays. You exit Vim and go enjoy yourselves, forgetting all about your work. After a couple @@ -168,6 +168,48 @@ The |:marks| command is useful to find out where '0 to '9 will take you. +GETTING BACK TO SOME FILE + +If you want to go back to a file that you edited recently, but not when +exiting Vim, there is a slightly more complicated way. You can see a list of +files by typing the command: > + + :oldfiles +< 1: ~/.viminfo ~ + 2: ~/text/resume.txt ~ + 3: /tmp/draft ~ + +Now you would like to edit the second file, which is in the list preceded by +"2:". You type: > + + :e #<2 + +Instead of ":e" you can use any command that has a file name argument, the +"#<2" item works in the same place as "%" (current file name) and "#" +(alternate file name). So you can also split the window to edit the third +file: > + + :split #<3 + +That #<123 thing is a bit complicated when you just want to edit a file. +Fortunately there is a simpler way: > + + :browse oldfiles +< 1: ~/.viminfo ~ + 2: ~/text/resume.txt ~ + 3: /tmp/draft ~ + -- More -- + +You get the same list of files as with |:oldfiles|. If you want to edit +"resume.txt" first press "q" to stop the listing. You will get a prompt: + + Type number and (empty cancels): ~ + +Type "2" and press to edit the second file. + +More info at |:oldfiles|, |v:oldfiles| and |c_#<|. + + MOVE INFO FROM ONE VIM TO ANOTHER You can use the ":wviminfo" and ":rviminfo" commands to save and restore the diff -Naur vim72.orig/runtime/scripts.vim vim72/runtime/scripts.vim --- vim72.orig/runtime/scripts.vim 2008-08-08 15:27:21.000000000 -0700 +++ vim72/runtime/scripts.vim 2009-03-22 21:27:09.826708758 -0700 @@ -234,6 +234,10 @@ elseif s:line1 =~ '\' + set ft=html + " PDF elseif s:line1 =~ '^%PDF-' set ft=pdf diff -Naur vim72.orig/src/auto/configure vim72/src/auto/configure --- vim72.orig/src/auto/configure 2008-07-24 05:40:36.000000000 -0700 +++ vim72/src/auto/configure 2009-03-22 21:32:18.746505099 -0700 @@ -11565,6 +11565,67 @@ fi +{ $as_echo "$as_me:$LINENO: checking for working volatile" >&5 +$as_echo_n "checking for working volatile... " >&6; } +if test "${ac_cv_c_volatile+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + +volatile int x; +int * volatile y = (int *) 0; +return !x && !y; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_volatile=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_volatile=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_volatile" >&5 +$as_echo "$ac_cv_c_volatile" >&6; } +if test $ac_cv_c_volatile = no; then + +cat >>confdefs.h <<\_ACEOF +#define volatile /**/ +_ACEOF + +fi + { $as_echo "$as_me:$LINENO: checking for mode_t" >&5 $as_echo_n "checking for mode_t... " >&6; } if test "${ac_cv_type_mode_t+set}" = set; then @@ -16819,21 +16880,29 @@ LDFLAGS="$LDFLAGS -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc" fi -{ $as_echo "$as_me:$LINENO: checking for GCC 3 or later" >&5 -$as_echo_n "checking for GCC 3 or later... " >&6; } DEPEND_CFLAGS_FILTER= if test "$GCC" = yes; then + { $as_echo "$as_me:$LINENO: checking for GCC 3 or later" >&5 +$as_echo_n "checking for GCC 3 or later... " >&6; } gccmajor=`echo "$gccversion" | sed -e 's/^\([1-9]\)\..*$/\1/g'` if test "$gccmajor" -gt "2"; then DEPEND_CFLAGS_FILTER="| sed 's+-I */+-isystem /+g'" - fi -fi -if test "$DEPEND_CFLAGS_FILTER" = ""; then - { $as_echo "$as_me:$LINENO: result: no" >&5 + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } -else - { $as_echo "$as_me:$LINENO: result: yes" >&5 + fi + { $as_echo "$as_me:$LINENO: checking whether we need -D_FORTIFY_SOURCE=1" >&5 +$as_echo_n "checking whether we need -D_FORTIFY_SOURCE=1... " >&6; } + if test "$gccmajor" -gt "3"; then + CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=1" + { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } + else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + fi fi diff -Naur vim72.orig/src/buffer.c vim72/src/buffer.c --- vim72.orig/src/buffer.c 2008-08-06 04:00:48.000000000 -0700 +++ vim72/src/buffer.c 2009-03-22 21:31:46.680450343 -0700 @@ -437,10 +437,6 @@ return; #endif -#ifdef FEAT_NETBEANS_INTG - if (usingNetbeans) - netbeans_file_closed(buf); -#endif /* Change directories when the 'acd' option is set. */ DO_AUTOCHDIR @@ -639,6 +635,10 @@ #ifdef FEAT_SIGNS buf_delete_signs(buf); /* delete any signs */ #endif +#ifdef FEAT_NETBEANS_INTG + if (usingNetbeans) + netbeans_file_killed(buf); +#endif #ifdef FEAT_LOCALMAP map_clear_int(buf, MAP_ALL_MODES, TRUE, FALSE); /* clear local mappings */ map_clear_int(buf, MAP_ALL_MODES, TRUE, TRUE); /* clear local abbrevs */ @@ -647,6 +647,9 @@ vim_free(buf->b_start_fenc); buf->b_start_fenc = NULL; #endif +#ifdef FEAT_SPELL + ga_clear(&buf->b_langp); +#endif } /* @@ -812,9 +815,6 @@ int bnr; /* buffer number */ char_u *p; -#ifdef FEAT_NETBEANS_INTG - netbeansCloseFile = 1; -#endif if (addr_count == 0) { (void)do_buffer(command, DOBUF_CURRENT, FORWARD, 0, forceit); @@ -909,9 +909,6 @@ } } -#ifdef FEAT_NETBEANS_INTG - netbeansCloseFile = 0; -#endif return errormsg; } @@ -1237,7 +1234,7 @@ * "buf" if one exists */ if ((swb_flags & SWB_USEOPEN) && buf_jump_open_win(buf)) return OK; - /* If 'switchbuf' contians "usetab": jump to first window in any tab + /* If 'switchbuf' contains "usetab": jump to first window in any tab * page containing "buf" if one exists */ if ((swb_flags & SWB_USETAB) && buf_jump_open_tab(buf)) return OK; @@ -1351,11 +1348,12 @@ } } #ifdef FEAT_AUTOCMD + /* An autocommand may have deleted "buf", already entered it (e.g., when + * it did ":bunload") or aborted the script processing! */ # ifdef FEAT_EVAL - /* An autocommand may have deleted buf or aborted the script processing! */ - if (buf_valid(buf) && !aborting()) + if (buf_valid(buf) && buf != curbuf && !aborting()) # else - if (buf_valid(buf)) /* an autocommand may have deleted buf! */ + if (buf_valid(buf) && buf != curbuf) # endif #endif enter_buffer(buf); @@ -1397,6 +1395,9 @@ curwin->w_cursor.coladd = 0; #endif curwin->w_set_curswant = TRUE; +#ifdef FEAT_AUTOCMD + curwin->w_topline_was_set = FALSE; +#endif /* Make sure the buffer is loaded. */ if (curbuf->b_ml.ml_mfp == NULL) /* need to load the file */ @@ -1436,7 +1437,8 @@ maketitle(); #endif #ifdef FEAT_AUTOCMD - if (curwin->w_topline == 1) /* when autocmds didn't change it */ + /* when autocmds didn't change it */ + if (curwin->w_topline == 1 && !curwin->w_topline_was_set) #endif scroll_cursor_halfway(FALSE); /* redisplay at correct position */ @@ -3963,7 +3965,7 @@ width = vim_strsize(out); if (maxwidth > 0 && width > maxwidth) { - /* Result is too long, must trunctate somewhere. */ + /* Result is too long, must truncate somewhere. */ l = 0; if (itemcnt == 0) s = out; @@ -5048,7 +5050,8 @@ */ FOR_ALL_TAB_WINDOWS(tp, win) if (win->w_buffer == buf) - break; + goto win_found; +win_found: if (win != NULL && win->w_llist_ref != NULL) return _("[Location List]"); else @@ -5062,7 +5065,7 @@ { if (buf->b_sfname != NULL) return (char *)buf->b_sfname; - return "[Scratch]"; + return _("[Scratch]"); } #endif if (buf->b_fname == NULL) diff -Naur vim72.orig/src/config.h.in vim72/src/config.h.in --- vim72.orig/src/config.h.in 2008-06-21 08:01:41.000000000 -0700 +++ vim72/src/config.h.in 2009-03-22 21:32:18.746505099 -0700 @@ -50,6 +50,9 @@ /* Define to empty if the keyword does not work. */ #undef const +/* Define to empty if the keyword does not work. */ +#undef volatile + /* Define to `int' if doesn't define. */ #undef mode_t diff -Naur vim72.orig/src/configure.in vim72/src/configure.in --- vim72.orig/src/configure.in 2008-07-24 05:40:26.000000000 -0700 +++ vim72/src/configure.in 2009-03-22 21:32:18.746505099 -0700 @@ -2148,6 +2148,7 @@ dnl Checks for typedefs, structures, and compiler characteristics. AC_PROG_GCC_TRADITIONAL AC_C_CONST +AC_C_VOLATILE AC_TYPE_MODE_T AC_TYPE_OFF_T AC_TYPE_PID_T @@ -3152,18 +3153,25 @@ dnl But only when making dependencies, cproto and lint don't take "-isystem". dnl Mac gcc returns "powerpc-apple-darwin8-gcc-4.0.1 (GCC)...", need to allow dnl the number before the version number. -AC_MSG_CHECKING(for GCC 3 or later) DEPEND_CFLAGS_FILTER= if test "$GCC" = yes; then + AC_MSG_CHECKING(for GCC 3 or later) gccmajor=`echo "$gccversion" | sed -e 's/^\([[1-9]]\)\..*$/\1/g'` if test "$gccmajor" -gt "2"; then DEPEND_CFLAGS_FILTER="| sed 's+-I */+-isystem /+g'" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + dnl -D_FORTIFY_SOURCE=2 crashes Vim on strcpy(buf, "000") when buf is + dnl declared as char x[1] but actually longer. Introduced in gcc 4.0. + AC_MSG_CHECKING(whether we need -D_FORTIFY_SOURCE=1) + if test "$gccmajor" -gt "3"; then + CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=1" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) fi -fi -if test "$DEPEND_CFLAGS_FILTER" = ""; then - AC_MSG_RESULT(no) -else - AC_MSG_RESULT(yes) fi AC_SUBST(DEPEND_CFLAGS_FILTER) diff -Naur vim72.orig/src/diff.c vim72/src/diff.c --- vim72.orig/src/diff.c 2008-03-05 03:16:56.000000000 -0800 +++ vim72/src/diff.c 2009-03-22 21:32:26.210983378 -0700 @@ -8,7 +8,7 @@ */ /* - * diff.c: code for diff'ing two or three buffers. + * diff.c: code for diff'ing two, three or four buffers. */ #include "vim.h" @@ -73,6 +73,8 @@ { tp->tp_diffbuf[i] = NULL; tp->tp_diff_invalid = TRUE; + if (tp == curtab) + diff_redraw(TRUE); } } } @@ -102,6 +104,7 @@ { curtab->tp_diffbuf[i] = NULL; curtab->tp_diff_invalid = TRUE; + diff_redraw(TRUE); } } } @@ -113,7 +116,7 @@ * Add a buffer to make diffs for. * Call this when a new buffer is being edited in the current window where * 'diff' is set. - * Marks the current buffer as being part of the diff and requireing updating. + * Marks the current buffer as being part of the diff and requiring updating. * This must be done before any autocmd, because a command may use info * about the screen contents. */ @@ -131,6 +134,7 @@ { curtab->tp_diffbuf[i] = buf; curtab->tp_diff_invalid = TRUE; + diff_redraw(TRUE); return; } @@ -661,6 +665,7 @@ char_u *tmp_diff; FILE *fd; int ok; + int io_error = FALSE; /* Delete all diffblocks. */ diff_clear(curtab); @@ -697,18 +702,26 @@ { ok = FALSE; fd = mch_fopen((char *)tmp_orig, "w"); - if (fd != NULL) + if (fd == NULL) + io_error = TRUE; + else { - fwrite("line1\n", (size_t)6, (size_t)1, fd); + if (fwrite("line1\n", (size_t)6, (size_t)1, fd) != 1) + io_error = TRUE; fclose(fd); fd = mch_fopen((char *)tmp_new, "w"); - if (fd != NULL) + if (fd == NULL) + io_error = TRUE; + else { - fwrite("line2\n", (size_t)6, (size_t)1, fd); + if (fwrite("line2\n", (size_t)6, (size_t)1, fd) != 1) + io_error = TRUE; fclose(fd); diff_file(tmp_orig, tmp_new, tmp_diff); fd = mch_fopen((char *)tmp_diff, "r"); - if (fd != NULL) + if (fd == NULL) + io_error = TRUE; + else { char_u linebuf[LBUFLEN]; @@ -761,6 +774,8 @@ } if (!ok) { + if (io_error) + EMSG(_("E810: Cannot read or write temp files")); EMSG(_("E97: Cannot create diffs")); diff_a_works = MAYBE; #if defined(MSWIN) || defined(MSDOS) @@ -914,7 +929,7 @@ goto theend; #ifdef UNIX - /* Temporaraly chdir to /tmp, to avoid patching files in the current + /* Temporarily chdir to /tmp, to avoid patching files in the current * directory when the patch file contains more than one patch. When we * have our own temp dir use that instead, it will be cleaned up when we * exit (any .rej files created). Don't change directory if we can't @@ -925,10 +940,10 @@ { # ifdef TEMPDIRNAMES if (vim_tempdir != NULL) - mch_chdir((char *)vim_tempdir); + ignored = mch_chdir((char *)vim_tempdir); else # endif - mch_chdir("/tmp"); + ignored = mch_chdir("/tmp"); shorten_fnames(TRUE); } #endif @@ -1138,7 +1153,7 @@ for (wp = firstwin; wp != NULL; wp = wp->w_next) { - if (wp == curwin || eap->forceit) + if (wp == curwin || (eap->forceit && wp->w_p_diff)) { /* Set 'diff', 'scrollbind' off and 'wrap' on. */ wp->w_p_diff = FALSE; @@ -2114,6 +2129,8 @@ EMSG2(_("E102: Can't find buffer \"%s\""), eap->arg); return; } + if (buf == curbuf) + return; /* nothing to do */ idx_other = diff_buf_idx(buf); if (idx_other == DB_COUNT) { diff -Naur vim72.orig/src/edit.c vim72/src/edit.c --- vim72.orig/src/edit.c 2008-08-06 05:51:17.000000000 -0700 +++ vim72/src/edit.c 2009-03-22 21:31:27.235204917 -0700 @@ -147,6 +147,7 @@ static int ins_compl_bs __ARGS((void)); static void ins_compl_new_leader __ARGS((void)); static void ins_compl_addleader __ARGS((int c)); +static int ins_compl_len __ARGS((void)); static void ins_compl_restart __ARGS((void)); static void ins_compl_set_original_text __ARGS((char_u *str)); static void ins_compl_addfrommatch __ARGS((void)); @@ -197,7 +198,8 @@ static void mb_replace_pop_ins __ARGS((int cc)); #endif static void replace_flush __ARGS((void)); -static void replace_do_bs __ARGS((void)); +static void replace_do_bs __ARGS((int limit_col)); +static int del_char_after_col __ARGS((int limit_col)); #ifdef FEAT_CINDENT static int cindent_on __ARGS((void)); #endif @@ -1933,6 +1935,8 @@ /* * Backspace the cursor until the given column. Handles REPLACE and VREPLACE * modes correctly. May also be used when not in insert mode at all. + * Will attempt not to go before "col" even when there is a composing + * character. */ void backspace_until_column(col) @@ -1942,13 +1946,50 @@ { curwin->w_cursor.col--; if (State & REPLACE_FLAG) - replace_do_bs(); - else - (void)del_char(FALSE); + replace_do_bs(col); + else if (!del_char_after_col(col)) + break; } } #endif +/* + * Like del_char(), but make sure not to go before column "limit_col". + * Only matters when there are composing characters. + * Return TRUE when something was deleted. + */ +/*ARGSUSED*/ + static int +del_char_after_col(limit_col) + int limit_col; +{ +#ifdef FEAT_MBYTE + if (enc_utf8 && limit_col >= 0) + { + int ecol = curwin->w_cursor.col + 1; + + /* Make sure the cursor is at the start of a character, but + * skip forward again when going too far back because of a + * composing character. */ + mb_adjust_cursor(); + while (curwin->w_cursor.col < (colnr_T)limit_col) + { + int l = utf_ptr2len(ml_get_cursor()); + + if (l == 0) /* end of line */ + break; + curwin->w_cursor.col += l; + } + if (*ml_get_cursor() == NUL || curwin->w_cursor.col == ecol) + return FALSE; + del_bytes((long)(ecol - curwin->w_cursor.col), FALSE, TRUE); + } + else +#endif + (void)del_char(FALSE); + return TRUE; +} + #if defined(FEAT_INS_EXPAND) || defined(PROTO) /* * CTRL-X pressed in Insert mode. @@ -2418,7 +2459,7 @@ { had_match = (curwin->w_cursor.col > compl_col); ins_compl_delete(); - ins_bytes(compl_leader + curwin->w_cursor.col - compl_col); + ins_bytes(compl_leader + ins_compl_len()); ins_redraw(FALSE); /* When the match isn't there (to avoid matching itself) remove it @@ -2470,7 +2511,7 @@ *p = NUL; had_match = (curwin->w_cursor.col > compl_col); ins_compl_delete(); - ins_bytes(compl_leader + curwin->w_cursor.col - compl_col); + ins_bytes(compl_leader + ins_compl_len()); ins_redraw(FALSE); /* When the match isn't there (to avoid matching itself) remove it @@ -3209,7 +3250,7 @@ { ins_compl_del_pum(); ins_compl_delete(); - ins_bytes(compl_leader + curwin->w_cursor.col - compl_col); + ins_bytes(compl_leader + ins_compl_len()); compl_used_match = FALSE; if (compl_started) @@ -3264,6 +3305,20 @@ } /* + * Return the length of the completion, from the completion start column to + * the cursor column. Making sure it never goes below zero. + */ + static int +ins_compl_len() +{ + int off = curwin->w_cursor.col - compl_col; + + if (off < 0) + return 0; + return off; +} + +/* * Append one character to the match leader. May reduce the number of * matches. */ @@ -3621,10 +3676,9 @@ { ins_compl_delete(); if (compl_leader != NULL) - ins_bytes(compl_leader + curwin->w_cursor.col - compl_col); + ins_bytes(compl_leader + ins_compl_len()); else if (compl_first_match != NULL) - ins_bytes(compl_orig_text - + curwin->w_cursor.col - compl_col); + ins_bytes(compl_orig_text + ins_compl_len()); retval = TRUE; } @@ -4187,7 +4241,7 @@ } /* check if compl_curr_match has changed, (e.g. other type of - * expansion added somenthing) */ + * expansion added something) */ if (type != 0 && compl_curr_match != old_match) found_new_match = OK; @@ -4256,7 +4310,7 @@ static void ins_compl_insert() { - ins_bytes(compl_shown_match->cp_str + curwin->w_cursor.col - compl_col); + ins_bytes(compl_shown_match->cp_str + ins_compl_len()); if (compl_shown_match->cp_flags & ORIGINAL_TEXT) compl_used_match = FALSE; else @@ -4425,7 +4479,7 @@ if (!compl_get_longest || compl_used_match) ins_compl_insert(); else - ins_bytes(compl_leader + curwin->w_cursor.col - compl_col); + ins_bytes(compl_leader + ins_compl_len()); } else compl_used_match = FALSE; @@ -4688,7 +4742,7 @@ } compl_length = curwin->w_cursor.col - (int)compl_col; /* IObuff is used to add a "word from the next line" would we - * have enough space? just being paranoic */ + * have enough space? just being paranoid */ #define MIN_SPACE 75 if (compl_length > (IOSIZE - MIN_SPACE)) { @@ -7123,9 +7177,12 @@ * cc == 0: character was inserted, delete it * cc > 0: character was replaced, put cc (first byte of original char) back * and check for more characters to be put back + * When "limit_col" is >= 0, don't delete before this column. Matters when + * using composing characters, use del_char_after_col() instead of del_char(). */ static void -replace_do_bs() +replace_do_bs(limit_col) + int limit_col; { int cc; #ifdef FEAT_VREPLACE @@ -7153,7 +7210,7 @@ #ifdef FEAT_MBYTE if (has_mbyte) { - del_char(FALSE); + (void)del_char_after_col(limit_col); # ifdef FEAT_VREPLACE if (State & VREPLACE_FLAG) orig_len = (int)STRLEN(ml_get_cursor()); @@ -7203,7 +7260,7 @@ changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col); } else if (cc == 0) - (void)del_char(FALSE); + (void)del_char_after_col(limit_col); } #ifdef FEAT_CINDENT @@ -7646,9 +7703,7 @@ */ ++no_mapping; regname = plain_vgetc(); -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(regname, TRUE); -#endif if (regname == Ctrl_R || regname == Ctrl_O || regname == Ctrl_P) { /* Get a third key for literal register insertion */ @@ -7657,9 +7712,7 @@ add_to_showcmd_c(literally); #endif regname = plain_vgetc(); -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(regname, TRUE); -#endif } --no_mapping; @@ -8150,7 +8203,7 @@ /* * If the cursor is on an indent, ^T/^D insert/delete one * shiftwidth. Otherwise ^T/^D behave like a "<<" or ">>". - * Always round the indent to 'shiftwith', this is compatible + * Always round the indent to 'shiftwidth', this is compatible * with vi. But vi only supports ^T and ^D after an * autoindent, we support it everywhere. */ @@ -8239,7 +8292,7 @@ * Replace mode */ if (curwin->w_cursor.lnum != Insstart.lnum || curwin->w_cursor.col >= Insstart.col) - replace_do_bs(); + replace_do_bs(-1); } else (void)del_char(FALSE); @@ -8556,7 +8609,7 @@ break; } if (State & REPLACE_FLAG) - replace_do_bs(); + replace_do_bs(-1); else { #ifdef FEAT_MBYTE diff -Naur vim72.orig/src/eval.c vim72/src/eval.c --- vim72.orig/src/eval.c 2008-08-07 12:37:22.000000000 -0700 +++ vim72/src/eval.c 2009-03-22 21:31:00.153469200 -0700 @@ -32,6 +32,9 @@ #define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */ +#define DO_NOT_FREE_CNT 99999 /* refcount for dict or list that should not + be freed. */ + /* * In a hashtab item "hi_key" points to "di_key" in a dictitem. * This avoids adding a pointer to the hashtab item. @@ -348,6 +351,7 @@ {VV_NAME("mouse_col", VAR_NUMBER), 0}, {VV_NAME("operator", VAR_STRING), VV_RO}, {VV_NAME("searchforward", VAR_NUMBER), 0}, + {VV_NAME("oldfiles", VAR_LIST), 0}, }; /* shorthand */ @@ -355,6 +359,7 @@ #define vv_nr vv_di.di_tv.vval.v_number #define vv_float vv_di.di_tv.vval.v_float #define vv_str vv_di.di_tv.vval.v_string +#define vv_list vv_di.di_tv.vval.v_list #define vv_tv vv_di.di_tv /* @@ -426,7 +431,6 @@ static long list_idx_of_item __ARGS((list_T *l, listitem_T *item)); static void list_append __ARGS((list_T *l, listitem_T *item)); static int list_append_tv __ARGS((list_T *l, typval_T *tv)); -static int list_append_string __ARGS((list_T *l, char_u *str, int len)); static int list_append_number __ARGS((list_T *l, varnumber_T n)); static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); @@ -788,6 +792,8 @@ static void func_unref __ARGS((char_u *name)); static void func_ref __ARGS((char_u *name)); static void call_user_func __ARGS((ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, linenr_T firstline, linenr_T lastline, dict_T *selfdict)); +static int can_free_funccal __ARGS((funccall_T *fc, int copyID)) ; +static void free_funccal __ARGS((funccall_T *fc, int free_val)); static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); static win_T *find_win_by_nr __ARGS((typval_T *vp, tabpage_T *tp)); static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off)); @@ -845,11 +851,17 @@ p = &vimvars[i]; if (p->vv_di.di_tv.v_type == VAR_STRING) { - vim_free(p->vv_di.di_tv.vval.v_string); - p->vv_di.di_tv.vval.v_string = NULL; + vim_free(p->vv_str); + p->vv_str = NULL; + } + else if (p->vv_di.di_tv.v_type == VAR_LIST) + { + list_unref(p->vv_list); + p->vv_list = NULL; } } hash_clear(&vimvarht); + hash_init(&vimvarht); /* garbage_collect() will access it */ hash_clear(&compat_hashtab); /* script-local variables */ @@ -916,6 +928,10 @@ /* pointer to funccal for currently active function */ funccall_T *current_funccal = NULL; +/* pointer to list of previously used funccal, still around because some + * item in it is still being used. */ +funccall_T *previous_funccal = NULL; + /* * Return TRUE when a function was ended by a ":return" command. */ @@ -1256,23 +1272,26 @@ /* * Top level evaluation function, returning a string. + * When "convert" is TRUE convert a List into a sequence of lines and convert + * a Float to a String. * Return pointer to allocated memory, or NULL for failure. */ char_u * -eval_to_string(arg, nextcmd, dolist) +eval_to_string(arg, nextcmd, convert) char_u *arg; char_u **nextcmd; - int dolist; /* turn List into sequence of lines */ + int convert; { typval_T tv; char_u *retval; garray_T ga; + char_u numbuf[NUMBUFLEN]; if (eval0(arg, &tv, nextcmd, TRUE) == FAIL) retval = NULL; else { - if (dolist && tv.v_type == VAR_LIST) + if (convert && tv.v_type == VAR_LIST) { ga_init2(&ga, (int)sizeof(char), 80); if (tv.vval.v_list != NULL) @@ -1280,6 +1299,13 @@ ga_append(&ga, NUL); retval = (char_u *)ga.ga_data; } +#ifdef FEAT_FLOAT + else if (convert && tv.v_type == VAR_FLOAT) + { + vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv.vval.v_float); + retval = vim_strsave(numbuf); + } +#endif else retval = vim_strsave(get_tv_string(&tv)); clear_tv(&tv); @@ -3277,7 +3303,7 @@ if (*startarg != '(') { - EMSG2(_("E107: Missing braces: %s"), eap->arg); + EMSG2(_("E107: Missing parentheses: %s"), eap->arg); goto end; } @@ -3657,8 +3683,8 @@ } /* - * Return TRUE if typeval "tv" is locked: Either tha value is locked itself or - * it refers to a List or Dictionary that is locked. + * Return TRUE if typeval "tv" is locked: Either that value is locked itself + * or it refers to a List or Dictionary that is locked. */ static int tv_islocked(tv) @@ -3902,7 +3928,7 @@ /* * Handle top level expression: - * expr1 ? expr0 : expr0 + * expr2 ? expr1 : expr1 * * "arg" must point to the first non-white of the expression. * "arg" is advanced to the next non-white after the recognized expression. @@ -6047,6 +6073,25 @@ } /* + * Get list item "l[idx - 1]" as a string. Returns NULL for failure. + */ + char_u * +list_find_str(l, idx) + list_T *l; + long idx; +{ + listitem_T *li; + + li = list_find(l, idx - 1); + if (li == NULL) + { + EMSGN(_(e_listidx), idx); + return NULL; + } + return get_tv_string(&li->li_tv); +} + +/* * Locate "item" list "l" and return its index. * Returns -1 when "item" is not in the list. */ @@ -6137,7 +6182,7 @@ * When "len" >= 0 use "str[len]". * Returns FAIL when out of memory. */ - static int + int list_append_string(l, str, len) list_T *l; char_u *str; @@ -6454,7 +6499,7 @@ buf_T *buf; win_T *wp; int i; - funccall_T *fc; + funccall_T *fc, **pfc; int did_free = FALSE; #ifdef FEAT_WINDOWS tabpage_T *tp; @@ -6497,6 +6542,9 @@ set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); } + /* v: vars */ + set_ref_in_ht(&vimvarht, copyID); + /* * 2. Go through the list of dicts and free items without the copyID. */ @@ -6535,6 +6583,20 @@ else ll = ll->lv_used_next; + /* check if any funccal can be freed now */ + for (pfc = &previous_funccal; *pfc != NULL; ) + { + if (can_free_funccal(*pfc, copyID)) + { + fc = *pfc; + *pfc = fc->caller; + free_funccal(fc, TRUE); + did_free = TRUE; + } + else + pfc = &(*pfc)->caller; + } + return did_free; } @@ -6587,7 +6649,7 @@ { case VAR_DICT: dd = tv->vval.v_dict; - if (dd->dv_copyID != copyID) + if (dd != NULL && dd->dv_copyID != copyID) { /* Didn't see this dict yet. */ dd->dv_copyID = copyID; @@ -6597,7 +6659,7 @@ case VAR_LIST: ll = tv->vval.v_list; - if (ll->lv_copyID != copyID) + if (ll != NULL && ll->lv_copyID != copyID) { /* Didn't see this list yet. */ ll->lv_copyID = copyID; @@ -7525,8 +7587,8 @@ {"getwinposx", 0, 0, f_getwinposx}, {"getwinposy", 0, 0, f_getwinposy}, {"getwinvar", 2, 2, f_getwinvar}, - {"glob", 1, 1, f_glob}, - {"globpath", 2, 2, f_globpath}, + {"glob", 1, 2, f_glob}, + {"globpath", 2, 3, f_globpath}, {"has", 1, 1, f_has}, {"has_key", 2, 2, f_has_key}, {"haslocaldir", 0, 0, f_haslocaldir}, @@ -7856,9 +7918,9 @@ else if (!aborting()) { if (argcount == MAX_FUNC_ARGS) - emsg_funcname("E740: Too many arguments for function %s", name); + emsg_funcname(N_("E740: Too many arguments for function %s"), name); else - emsg_funcname("E116: Invalid arguments for function %s", name); + emsg_funcname(N_("E116: Invalid arguments for function %s"), name); } while (--argcount >= 0) @@ -8091,6 +8153,7 @@ /* * Give an error message with a function name. Handle things. + * "ermsg" is to be passed without translation, use N_() instead of _(). */ static void emsg_funcname(ermsg, name) @@ -9518,7 +9581,7 @@ else { /* When the optional second argument is non-zero, don't remove matches - * for 'suffixes' and 'wildignore' */ + * for 'wildignore' and don't put matches for 'suffixes' at the end. */ if (argvars[1].v_type != VAR_UNKNOWN && get_tv_number_chk(&argvars[1], &error)) flags |= WILD_KEEP_ALL; @@ -10300,7 +10363,8 @@ s = get_tv_string(&argvars[0]); if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) EMSG2(_(e_invarg2), s); - else if (!function_exists(s)) + /* Don't check an autoload name for existence here. */ + else if (vim_strchr(s, AUTOLOAD_CHAR) == NULL && !function_exists(s)) EMSG2(_("E700: Unknown function: %s"), s); else { @@ -10602,7 +10666,7 @@ # ifdef FEAT_WINDOWS win_T *wp; # endif - int n = 1; + int winnr = 1; if (row >= 0 && col >= 0) { @@ -10612,9 +10676,9 @@ (void)mouse_comp_pos(win, &row, &col, &lnum); # ifdef FEAT_WINDOWS for (wp = firstwin; wp != win; wp = wp->w_next) - ++n; + ++winnr; # endif - vimvars[VV_MOUSE_WIN].vv_nr = n; + vimvars[VV_MOUSE_WIN].vv_nr = winnr; vimvars[VV_MOUSE_LNUM].vv_nr = lnum; vimvars[VV_MOUSE_COL].vv_nr = col + 1; } @@ -11284,13 +11348,25 @@ typval_T *argvars; typval_T *rettv; { + int flags = WILD_SILENT|WILD_USE_NL; expand_T xpc; + int error = FALSE; - ExpandInit(&xpc); - xpc.xp_context = EXPAND_FILES; + /* When the optional second argument is non-zero, don't remove matches + * for 'wildignore' and don't put matches for 'suffixes' at the end. */ + if (argvars[1].v_type != VAR_UNKNOWN + && get_tv_number_chk(&argvars[1], &error)) + flags |= WILD_KEEP_ALL; rettv->v_type = VAR_STRING; - rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), - NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); + if (!error) + { + ExpandInit(&xpc); + xpc.xp_context = EXPAND_FILES; + rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), + NULL, flags, WILD_ALL); + } + else + rettv->vval.v_string = NULL; } /* @@ -11301,14 +11377,22 @@ typval_T *argvars; typval_T *rettv; { + int flags = 0; char_u buf1[NUMBUFLEN]; char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); + int error = FALSE; + /* When the optional second argument is non-zero, don't remove matches + * for 'wildignore' and don't put matches for 'suffixes' at the end. */ + if (argvars[2].v_type != VAR_UNKNOWN + && get_tv_number_chk(&argvars[2], &error)) + flags |= WILD_KEEP_ALL; rettv->v_type = VAR_STRING; - if (file == NULL) + if (file == NULL || error) rettv->vval.v_string = NULL; else - rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file); + rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file, + flags); } /* @@ -11782,6 +11866,10 @@ n = has_patch(atoi((char *)name + 5)); else if (STRICMP(name, "vim_starting") == 0) n = (starting != 0); +#ifdef FEAT_MBYTE + else if (STRICMP(name, "multi_byte_encoding") == 0) + n = has_mbyte; +#endif #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) else if (STRICMP(name, "balloon_multiline") == 0) n = multiline_balloon_available(); @@ -15838,10 +15926,9 @@ if (res == FAIL) res = ITEM_COMPARE_FAIL; else - /* return value has wrong type */ res = get_tv_number_chk(&rettv, &item_compare_func_err); if (item_compare_func_err) - res = ITEM_COMPARE_FAIL; + res = ITEM_COMPARE_FAIL; /* return value has wrong type */ clear_tv(&rettv); return res; } @@ -16590,8 +16677,11 @@ p = highlight_has_attr(id, HL_INVERSE, modec); break; - case 's': /* standout */ - p = highlight_has_attr(id, HL_STANDOUT, modec); + case 's': + if (TOLOWER_ASC(what[1]) == 'p') /* sp[#] */ + p = highlight_color(id, what, modec); + else /* standout */ + p = highlight_has_attr(id, HL_STANDOUT, modec); break; case 'u': @@ -16658,7 +16748,7 @@ col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count - && col >= 0 && col < (long)STRLEN(ml_get(lnum)) + && col >= 0 && (col == 0 || col < (long)STRLEN(ml_get(lnum))) && rettv_list_alloc(rettv) != FAIL) { (void)syn_get_id(curwin, lnum, (colnr_T)col, FALSE, NULL, TRUE); @@ -18097,14 +18187,28 @@ } /* - * Set v:count, v:count1 and v:prevcount. + * Get List v: variable value. Caller must take care of reference count when + * needed. + */ + list_T * +get_vim_var_list(idx) + int idx; +{ + return vimvars[idx].vv_list; +} + +/* + * Set v:count to "count" and v:count1 to "count1". + * When "set_prevcount" is TRUE first set v:prevcount from v:count. */ void -set_vcount(count, count1) +set_vcount(count, count1, set_prevcount) long count; long count1; + int set_prevcount; { - vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; + if (set_prevcount) + vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; vimvars[VV_COUNT].vv_nr = count; vimvars[VV_COUNT1].vv_nr = count1; } @@ -18132,6 +18236,20 @@ } /* + * Set List v: variable to "val". + */ + void +set_vim_var_list(idx, val) + int idx; + list_T *val; +{ + list_unref(vimvars[idx].vv_list); + vimvars[idx].vv_list = val; + if (val != NULL) + ++val->lv_refcount; +} + +/* * Set v:register if needed. */ void @@ -18868,7 +18986,7 @@ dictitem_T *dict_var; { hash_init(&dict->dv_hashtab); - dict->dv_refcount = 99999; + dict->dv_refcount = DO_NOT_FREE_CNT; dict_var->di_tv.vval.v_dict = dict; dict_var->di_tv.v_type = VAR_DICT; dict_var->di_tv.v_lock = VAR_FIXED; @@ -19205,6 +19323,8 @@ * Copy the values from typval_T "from" to typval_T "to". * When needed allocates string or increases reference count. * Does not make a copy of a list or dict but copies the reference! + * It is OK for "from" and "to" to point to the same item. This is used to + * make a copy later. */ static void copy_tv(from, to) @@ -19748,7 +19868,7 @@ } } else - emsg_funcname("E123: Undefined function: %s", name); + emsg_funcname(N_("E123: Undefined function: %s"), name); } goto ret_free; } @@ -19792,7 +19912,7 @@ : eval_isnamec(arg[j]))) ++j; if (arg[j] != NUL) - emsg_funcname(_(e_invarg2), arg); + emsg_funcname((char *)e_invarg2, arg); } } @@ -20064,7 +20184,7 @@ v = find_var(name, &ht); if (v != NULL && v->di_tv.v_type == VAR_FUNC) { - emsg_funcname("E707: Function name conflicts with variable: %s", + emsg_funcname(N_("E707: Function name conflicts with variable: %s"), name); goto erret; } @@ -20079,7 +20199,7 @@ } if (fp->uf_calls > 0) { - emsg_funcname("E127: Cannot redefine function %s: It is in use", + emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"), name); goto erret; } @@ -20590,6 +20710,9 @@ int st_len = 0; todo = (int)func_hashtab.ht_used; + if (todo == 0) + return; /* nothing to dump */ + sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); for (hi = func_hashtab.ht_array; todo > 0; ++hi) @@ -20638,6 +20761,8 @@ prof_self_cmp); prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); } + + vim_free(sorttab); } static void @@ -21012,7 +21137,7 @@ char_u *save_sourcing_name; linenr_T save_sourcing_lnum; scid_T save_current_SID; - funccall_T fc; + funccall_T *fc; int save_did_emsg; static int depth = 0; dictitem_T *v; @@ -21038,36 +21163,37 @@ line_breakcheck(); /* check for CTRL-C hit */ - fc.caller = current_funccal; - current_funccal = &fc; - fc.func = fp; - fc.rettv = rettv; + fc = (funccall_T *)alloc(sizeof(funccall_T)); + fc->caller = current_funccal; + current_funccal = fc; + fc->func = fp; + fc->rettv = rettv; rettv->vval.v_number = 0; - fc.linenr = 0; - fc.returned = FALSE; - fc.level = ex_nesting_level; + fc->linenr = 0; + fc->returned = FALSE; + fc->level = ex_nesting_level; /* Check if this function has a breakpoint. */ - fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); - fc.dbg_tick = debug_tick; + fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); + fc->dbg_tick = debug_tick; /* - * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables + * Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free * each argument variable and saves a lot of time. */ /* * Init l: variables. */ - init_var_dict(&fc.l_vars, &fc.l_vars_var); + init_var_dict(&fc->l_vars, &fc->l_vars_var); if (selfdict != NULL) { /* Set l:self to "selfdict". Use "name" to avoid a warning from * some compiler that checks the destination size. */ - v = &fc.fixvar[fixvar_idx++].var; + v = &fc->fixvar[fixvar_idx++].var; name = v->di_key; STRCPY(name, "self"); v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; - hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v)); + hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v)); v->di_tv.v_type = VAR_DICT; v->di_tv.v_lock = 0; v->di_tv.vval.v_dict = selfdict; @@ -21079,28 +21205,31 @@ * Set a:0 to "argcount". * Set a:000 to a list with room for the "..." arguments. */ - init_var_dict(&fc.l_avars, &fc.l_avars_var); - add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0", + init_var_dict(&fc->l_avars, &fc->l_avars_var); + add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0", (varnumber_T)(argcount - fp->uf_args.ga_len)); - v = &fc.fixvar[fixvar_idx++].var; - STRCPY(v->di_key, "000"); + /* Use "name" to avoid a warning from some compiler that checks the + * destination size. */ + v = &fc->fixvar[fixvar_idx++].var; + name = v->di_key; + STRCPY(name, "000"); v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; - hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); + hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v)); v->di_tv.v_type = VAR_LIST; v->di_tv.v_lock = VAR_FIXED; - v->di_tv.vval.v_list = &fc.l_varlist; - vim_memset(&fc.l_varlist, 0, sizeof(list_T)); - fc.l_varlist.lv_refcount = 99999; - fc.l_varlist.lv_lock = VAR_FIXED; + v->di_tv.vval.v_list = &fc->l_varlist; + vim_memset(&fc->l_varlist, 0, sizeof(list_T)); + fc->l_varlist.lv_refcount = DO_NOT_FREE_CNT; + fc->l_varlist.lv_lock = VAR_FIXED; /* * Set a:firstline to "firstline" and a:lastline to "lastline". * Set a:name to named arguments. * Set a:N to the "..." arguments. */ - add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline", + add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "firstline", (varnumber_T)firstline); - add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline", + add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "lastline", (varnumber_T)lastline); for (i = 0; i < argcount; ++i) { @@ -21116,7 +21245,7 @@ } if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) { - v = &fc.fixvar[fixvar_idx++].var; + v = &fc->fixvar[fixvar_idx++].var; v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; } else @@ -21128,7 +21257,7 @@ v->di_flags = DI_FLAGS_RO; } STRCPY(v->di_key, name); - hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); + hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v)); /* Note: the values are copied directly to avoid alloc/free. * "argvars" must have VAR_FIXED for v_lock. */ @@ -21137,9 +21266,9 @@ if (ai >= 0 && ai < MAX_FUNC_ARGS) { - list_append(&fc.l_varlist, &fc.l_listitems[ai]); - fc.l_listitems[ai].li_tv = argvars[i]; - fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED; + list_append(&fc->l_varlist, &fc->l_listitems[ai]); + fc->l_listitems[ai].li_tv = argvars[i]; + fc->l_listitems[ai].li_tv.v_lock = VAR_FIXED; } } @@ -21204,7 +21333,7 @@ if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) func_do_profile(fp); if (fp->uf_profiling - || (fc.caller != NULL && &fc.caller->func->uf_profiling)) + || (fc->caller != NULL && fc->caller->func->uf_profiling)) { ++fp->uf_tm_count; profile_start(&call_start); @@ -21220,7 +21349,7 @@ did_emsg = FALSE; /* call do_cmdline() to execute the lines */ - do_cmdline(NULL, get_func_line, (void *)&fc, + do_cmdline(NULL, get_func_line, (void *)fc, DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); --RedrawingDisabled; @@ -21235,16 +21364,16 @@ #ifdef FEAT_PROFILE if (do_profiling == PROF_YES && (fp->uf_profiling - || (fc.caller != NULL && &fc.caller->func->uf_profiling))) + || (fc->caller != NULL && fc->caller->func->uf_profiling))) { profile_end(&call_start); profile_sub_wait(&wait_start, &call_start); profile_add(&fp->uf_tm_total, &call_start); profile_self(&fp->uf_tm_self, &call_start, &fp->uf_tm_children); - if (fc.caller != NULL && &fc.caller->func->uf_profiling) + if (fc->caller != NULL && fc->caller->func->uf_profiling) { - profile_add(&fc.caller->func->uf_tm_children, &call_start); - profile_add(&fc.caller->func->uf_tml_children, &call_start); + profile_add(&fc->caller->func->uf_tm_children, &call_start); + profile_add(&fc->caller->func->uf_tml_children, &call_start); } } #endif @@ -21257,9 +21386,9 @@ if (aborting()) smsg((char_u *)_("%s aborted"), sourcing_name); - else if (fc.rettv->v_type == VAR_NUMBER) + else if (fc->rettv->v_type == VAR_NUMBER) smsg((char_u *)_("%s returning #%ld"), sourcing_name, - (long)fc.rettv->vval.v_number); + (long)fc->rettv->vval.v_number); else { char_u buf[MSG_BUF_LEN]; @@ -21270,7 +21399,7 @@ /* The value may be very long. Skip the middle part, so that we * have some idea how it starts and ends. smsg() would always * truncate it at the end. */ - s = tv2string(fc.rettv, &tofree, numbuf2, 0); + s = tv2string(fc->rettv, &tofree, numbuf2, 0); if (s != NULL) { trunc_string(s, buf, MSG_BUF_CLEN); @@ -21306,14 +21435,84 @@ } did_emsg |= save_did_emsg; - current_funccal = fc.caller; + current_funccal = fc->caller; + --depth; - /* The a: variables typevals were not allocated, only free the allocated - * variables. */ - vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE); + /* if the a:000 list and the a: dict are not referenced we can free the + * funccall_T and what's in it. */ + if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT + && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT + && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT) + { + free_funccal(fc, FALSE); + } + else + { + hashitem_T *hi; + listitem_T *li; + int todo; - vars_clear(&fc.l_vars.dv_hashtab); /* free all l: variables */ - --depth; + /* "fc" is still in use. This can happen when returning "a:000" or + * assigning "l:" to a global variable. + * Link "fc" in the list for garbage collection later. */ + fc->caller = previous_funccal; + previous_funccal = fc; + + /* Make a copy of the a: variables, since we didn't do that above. */ + todo = (int)fc->l_avars.dv_hashtab.ht_used; + for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi) + { + if (!HASHITEM_EMPTY(hi)) + { + --todo; + v = HI2DI(hi); + copy_tv(&v->di_tv, &v->di_tv); + } + } + + /* Make a copy of the a:000 items, since we didn't do that above. */ + for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next) + copy_tv(&li->li_tv, &li->li_tv); + } +} + +/* + * Return TRUE if items in "fc" do not have "copyID". That means they are not + * referenced from anywhere. + */ + static int +can_free_funccal(fc, copyID) + funccall_T *fc; + int copyID; +{ + return (fc->l_varlist.lv_copyID != copyID + && fc->l_vars.dv_copyID != copyID + && fc->l_avars.dv_copyID != copyID); +} + +/* + * Free "fc" and what it contains. + */ + static void +free_funccal(fc, free_val) + funccall_T *fc; + int free_val; /* a: vars were allocated */ +{ + listitem_T *li; + + /* The a: variables typevals may not have been allocated, only free the + * allocated variables. */ + vars_clear_ext(&fc->l_avars.dv_hashtab, free_val); + + /* free all l: variables */ + vars_clear(&fc->l_vars.dv_hashtab); + + /* Free the a:000 variables if they were allocated. */ + if (free_val) + for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next) + clear_tv(&li->li_tv); + + vim_free(fc); } /* @@ -21886,6 +22085,62 @@ } } +/* + * List v:oldfiles in a nice way. + */ +/*ARGSUSED*/ + void +ex_oldfiles(eap) + exarg_T *eap; +{ + list_T *l = vimvars[VV_OLDFILES].vv_list; + listitem_T *li; + int nr = 0; + + if (l == NULL) + msg((char_u *)_("No old files")); + else + { + msg_start(); + msg_scroll = TRUE; + for (li = l->lv_first; li != NULL && !got_int; li = li->li_next) + { + msg_outnum((long)++nr); + MSG_PUTS(": "); + msg_outtrans(get_tv_string(&li->li_tv)); + msg_putchar('\n'); + out_flush(); /* output one line at a time */ + ui_breakcheck(); + } + /* Assume "got_int" was set to truncate the listing. */ + got_int = FALSE; + +#ifdef FEAT_BROWSE_CMD + if (cmdmod.browse) + { + quit_more = FALSE; + nr = prompt_for_number(FALSE); + msg_starthere(); + if (nr > 0) + { + char_u *p = list_find_str(get_vim_var_list(VV_OLDFILES), + (long)nr); + + if (p != NULL) + { + p = expand_env_save(p); + eap->arg = p; + eap->cmdidx = CMD_edit; + cmdmod.browse = FALSE; + do_exedit(eap, NULL); + vim_free(p); + } + } + } +#endif + } +} + #endif /* FEAT_EVAL */ diff -Naur vim72.orig/src/ex_cmds2.c vim72/src/ex_cmds2.c --- vim72.orig/src/ex_cmds2.c 2008-07-13 09:18:22.000000000 -0700 +++ vim72/src/ex_cmds2.c 2009-03-22 21:31:09.882091074 -0700 @@ -2842,6 +2842,7 @@ linenr_T save_sourcing_lnum; char_u *p; char_u *fname_exp; + char_u *firstline = NULL; int retval = FAIL; #ifdef FEAT_EVAL scid_T save_current_SID; @@ -2992,23 +2993,6 @@ cookie.level = ex_nesting_level; #endif -#ifdef FEAT_MBYTE - cookie.conv.vc_type = CONV_NONE; /* no conversion */ - - /* Try reading the first few bytes to check for a UTF-8 BOM. */ - { - char_u buf[3]; - - if (fread((char *)buf, sizeof(char_u), (size_t)3, cookie.fp) - == (size_t)3 - && buf[0] == 0xef && buf[1] == 0xbb && buf[2] == 0xbf) - /* Found BOM, setup conversion and skip over it. */ - convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc); - else - /* No BOM found, rewind. */ - fseek(cookie.fp, 0L, SEEK_SET); - } -#endif /* * Keep the sourcing name/lnum, for recursive calls. @@ -3018,6 +3002,27 @@ save_sourcing_lnum = sourcing_lnum; sourcing_lnum = 0; +#ifdef FEAT_MBYTE + cookie.conv.vc_type = CONV_NONE; /* no conversion */ + + /* Read the first line so we can check for a UTF-8 BOM. */ + firstline = getsourceline(0, (void *)&cookie, 0); + if (firstline != NULL && STRLEN(firstline) >= 3 && firstline[0] == 0xef + && firstline[1] == 0xbb && firstline[2] == 0xbf) + { + /* Found BOM; setup conversion, skip over BOM and recode the line. */ + convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc); + p = string_convert(&cookie.conv, firstline + 3, NULL); + if (p == NULL) + p = vim_strsave(firstline + 3); + if (p != NULL) + { + vim_free(firstline); + firstline = p; + } + } +#endif + #ifdef STARTUPTIME time_push(&tv_rel, &tv_start); #endif @@ -3111,9 +3116,8 @@ /* * Call do_cmdline, which will call getsourceline() to get the lines. */ - do_cmdline(NULL, getsourceline, (void *)&cookie, + do_cmdline(firstline, getsourceline, (void *)&cookie, DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_REPEAT); - retval = OK; #ifdef FEAT_PROFILE @@ -3145,8 +3149,8 @@ verbose_leave(); } #ifdef STARTUPTIME - vim_snprintf(IObuff, IOSIZE, "sourcing %s", fname); - time_msg(IObuff, &tv_start); + vim_snprintf((char *)IObuff, IOSIZE, "sourcing %s", fname); + time_msg((char *)IObuff, &tv_start); time_pop(&tv_rel); #endif @@ -3171,6 +3175,7 @@ #endif fclose(cookie.fp); vim_free(cookie.nextline); + vim_free(firstline); #ifdef FEAT_MBYTE convert_setup(&cookie.conv, NULL, NULL); #endif diff -Naur vim72.orig/src/ex_cmds.c vim72/src/ex_cmds.c --- vim72.orig/src/ex_cmds.c 2008-08-04 12:15:00.000000000 -0700 +++ vim72/src/ex_cmds.c 2009-03-22 21:32:08.697861154 -0700 @@ -24,7 +24,7 @@ static void do_filter __ARGS((linenr_T line1, linenr_T line2, exarg_T *eap, char_u *cmd, int do_in, int do_out)); #ifdef FEAT_VIMINFO static char_u *viminfo_filename __ARGS((char_u *)); -static void do_viminfo __ARGS((FILE *fp_in, FILE *fp_out, int want_info, int want_marks, int force_read)); +static void do_viminfo __ARGS((FILE *fp_in, FILE *fp_out, int flags)); static int viminfo_encoding __ARGS((vir_T *virp)); static int read_viminfo_up_to_marks __ARGS((vir_T *virp, int forceit, int writing)); #endif @@ -49,6 +49,7 @@ exarg_T *eap; { int c; + int cval; char buf1[20]; char buf2[20]; char_u buf3[7]; @@ -75,6 +76,10 @@ { if (c == NL) /* NUL is stored as NL */ c = NUL; + if (c == CAR && get_fileformat(curbuf) == EOL_MAC) + cval = NL; /* NL is stored as CR */ + else + cval = c; if (vim_isprintc_strict(c) && (c < ' ' #ifndef EBCDIC || c > '~' @@ -94,7 +99,7 @@ buf2[0] = NUL; vim_snprintf((char *)IObuff, IOSIZE, _("<%s>%s%s %d, Hex %02x, Octal %03o"), - transchar(c), buf1, buf2, c, c, c); + transchar(c), buf1, buf2, cval, cval, cval); #ifdef FEAT_MBYTE if (enc_utf8) c = cc[ci++]; @@ -1676,14 +1681,12 @@ /* * read_viminfo() -- Read the viminfo file. Registers etc. which are already - * set are not over-written unless force is TRUE. -- webb + * set are not over-written unless "flags" includes VIF_FORCEIT. -- webb */ int -read_viminfo(file, want_info, want_marks, forceit) - char_u *file; - int want_info; - int want_marks; - int forceit; +read_viminfo(file, flags) + char_u *file; /* file name or NULL to use default name */ + int flags; /* VIF_WANT_INFO et al. */ { FILE *fp; char_u *fname; @@ -1691,7 +1694,7 @@ if (no_viminfo()) return FAIL; - fname = viminfo_filename(file); /* may set to default if NULL */ + fname = viminfo_filename(file); /* get file name in allocated buffer */ if (fname == NULL) return FAIL; fp = mch_fopen((char *)fname, READBIN); @@ -1701,8 +1704,9 @@ verbose_enter(); smsg((char_u *)_("Reading viminfo file \"%s\"%s%s%s"), fname, - want_info ? _(" info") : "", - want_marks ? _(" marks") : "", + (flags & VIF_WANT_INFO) ? _(" info") : "", + (flags & VIF_WANT_MARKS) ? _(" marks") : "", + (flags & VIF_GET_OLDFILES) ? _(" oldfiles") : "", fp == NULL ? _(" FAILED") : ""); verbose_leave(); } @@ -1712,10 +1716,9 @@ return FAIL; viminfo_errcnt = 0; - do_viminfo(fp, NULL, want_info, want_marks, forceit); + do_viminfo(fp, NULL, flags); fclose(fp); - return OK; } @@ -1943,7 +1946,7 @@ * root. */ if (fp_out != NULL) - (void)fchown(fileno(fp_out), st_old.st_uid, st_old.st_gid); + ignored = fchown(fileno(fp_out), st_old.st_uid, st_old.st_gid); #endif } } @@ -1968,7 +1971,7 @@ } viminfo_errcnt = 0; - do_viminfo(fp_in, fp_out, !forceit, !forceit, FALSE); + do_viminfo(fp_in, fp_out, forceit ? 0 : (VIF_WANT_INFO | VIF_WANT_MARKS)); fclose(fp_out); /* errors are ignored !? */ if (fp_in != NULL) @@ -2041,12 +2044,10 @@ * do_viminfo() -- Should only be called from read_viminfo() & write_viminfo(). */ static void -do_viminfo(fp_in, fp_out, want_info, want_marks, force_read) +do_viminfo(fp_in, fp_out, flags) FILE *fp_in; FILE *fp_out; - int want_info; - int want_marks; - int force_read; + int flags; { int count = 0; int eof = FALSE; @@ -2061,8 +2062,9 @@ if (fp_in != NULL) { - if (want_info) - eof = read_viminfo_up_to_marks(&vir, force_read, fp_out != NULL); + if (flags & VIF_WANT_INFO) + eof = read_viminfo_up_to_marks(&vir, + flags & VIF_FORCEIT, fp_out != NULL); else /* Skip info, find start of marks */ while (!(eof = viminfo_readline(&vir)) @@ -2092,8 +2094,9 @@ write_viminfo_bufferlist(fp_out); count = write_viminfo_marks(fp_out); } - if (fp_in != NULL && want_marks) - copy_viminfo_marks(&vir, fp_out, count, eof); + if (fp_in != NULL + && (flags & (VIF_WANT_MARKS | VIF_GET_OLDFILES | VIF_FORCEIT))) + copy_viminfo_marks(&vir, fp_out, count, eof, flags); vim_free(vir.vir_line); #ifdef FEAT_MBYTE @@ -2414,8 +2417,8 @@ cursor_on(); /* msg_start() switches it off */ out_flush(); silent_mode = save_silent; - info_message = FALSE; } + info_message = FALSE; } /* @@ -2704,7 +2707,12 @@ if (eap->cmdidx == CMD_saveas) { if (retval == OK) + { curbuf->b_p_ro = FALSE; +#ifdef FEAT_WINDOWS + redraw_tabline = TRUE; +#endif + } /* Change directories when the 'acd' option is set. */ DO_AUTOCHDIR } @@ -5059,6 +5067,7 @@ if (did_sub) ++sub_nlines; + vim_free(new_start); /* for when substitute was cancelled */ vim_free(sub_firstline); /* free the copy of the original line */ sub_firstline = NULL; } @@ -6520,6 +6529,7 @@ static int last_sign_typenr = MAX_TYPENR; /* is decremented */ static void sign_list_defined __ARGS((sign_T *sp)); +static void sign_undefine __ARGS((sign_T *sp, sign_T *sp_prev)); /* * ":sign" command @@ -6728,24 +6738,8 @@ /* ":sign list {name}" */ sign_list_defined(sp); else - { /* ":sign undefine {name}" */ - vim_free(sp->sn_name); - vim_free(sp->sn_icon); -#ifdef FEAT_SIGN_ICONS - if (sp->sn_image != NULL) - { - out_flush(); - gui_mch_destroy_sign(sp->sn_image); - } -#endif - vim_free(sp->sn_text); - if (sp_prev == NULL) - first_sign = sp->sn_next; - else - sp_prev->sn_next = sp->sn_next; - vim_free(sp); - } + sign_undefine(sp, sp_prev); } } else @@ -6994,6 +6988,31 @@ } /* + * Undefine a sign and free its memory. + */ + static void +sign_undefine(sp, sp_prev) + sign_T *sp; + sign_T *sp_prev; +{ + vim_free(sp->sn_name); + vim_free(sp->sn_icon); +#ifdef FEAT_SIGN_ICONS + if (sp->sn_image != NULL) + { + out_flush(); + gui_mch_destroy_sign(sp->sn_image); + } +#endif + vim_free(sp->sn_text); + if (sp_prev == NULL) + first_sign = sp->sn_next; + else + sp_prev->sn_next = sp->sn_next; + vim_free(sp); +} + +/* * Get highlighting attribute for sign "typenr". * If "line" is TRUE: line highl, if FALSE: text highl. */ @@ -7067,6 +7086,18 @@ return (char_u *)_("[Deleted]"); } +#if defined(EXITFREE) || defined(PROTO) +/* + * Undefine/free all signs. + */ + void +free_signs() +{ + while (first_sign != NULL) + sign_undefine(first_sign, NULL); +} +#endif + #endif #if defined(FEAT_GUI) || defined(FEAT_CLIENTSERVER) || defined(PROTO) diff -Naur vim72.orig/src/ex_cmds.h vim72/src/ex_cmds.h --- vim72.orig/src/ex_cmds.h 2008-06-21 11:47:57.000000000 -0700 +++ vim72/src/ex_cmds.h 2009-03-22 21:28:12.894752340 -0700 @@ -278,7 +278,7 @@ EX(CMD_crewind, "crewind", ex_cc, RANGE|NOTADR|COUNT|TRLBAR|BANG), EX(CMD_cscope, "cscope", do_cscope, - EXTRA|NOTRLCOM|SBOXOK|XFILE), + EXTRA|NOTRLCOM|XFILE), EX(CMD_cstag, "cstag", do_cstag, BANG|TRLBAR|WORD1), EX(CMD_cunmap, "cunmap", ex_unmap, @@ -506,7 +506,7 @@ EX(CMD_lclose, "lclose", ex_cclose, RANGE|NOTADR|COUNT|TRLBAR), EX(CMD_lcscope, "lcscope", do_cscope, - EXTRA|NOTRLCOM|SBOXOK|XFILE), + EXTRA|NOTRLCOM|XFILE), EX(CMD_left, "left", ex_align, TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY), EX(CMD_leftabove, "leftabove", ex_wrongmodifier, @@ -635,6 +635,8 @@ RANGE|NOTADR|ZEROR|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), EX(CMD_noremap, "noremap", ex_map, BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), +EX(CMD_noautocmd, "noautocmd", ex_wrongmodifier, + NEEDARG|EXTRA|NOTRLCOM), EX(CMD_nohlsearch, "nohlsearch", ex_nohlsearch, TRLBAR|SBOXOK|CMDWIN), EX(CMD_noreabbrev, "noreabbrev", ex_abbreviate, @@ -651,6 +653,8 @@ EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), EX(CMD_open, "open", ex_open, RANGE|EXTRA), +EX(CMD_oldfiles, "oldfiles", ex_oldfiles, + BANG|TRLBAR|SBOXOK|CMDWIN), EX(CMD_omap, "omap", ex_map, EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), EX(CMD_omapclear, "omapclear", ex_mapclear, @@ -802,7 +806,7 @@ EX(CMD_scriptencoding, "scriptencoding", ex_scriptencoding, WORD1|TRLBAR|CMDWIN), EX(CMD_scscope, "scscope", do_scscope, - EXTRA|NOTRLCOM|SBOXOK), + EXTRA|NOTRLCOM), EX(CMD_set, "set", ex_set, TRLBAR|EXTRA|CMDWIN|SBOXOK), EX(CMD_setfiletype, "setfiletype", ex_setfiletype, diff -Naur vim72.orig/src/ex_docmd.c vim72/src/ex_docmd.c --- vim72.orig/src/ex_docmd.c 2008-07-26 04:51:05.000000000 -0700 +++ vim72/src/ex_docmd.c 2009-03-22 21:32:51.508603437 -0700 @@ -364,6 +364,7 @@ # define ex_function ex_ni # define ex_delfunction ex_ni # define ex_return ex_ni +# define ex_oldfiles ex_ni #endif static char_u *arg_all __ARGS((void)); #ifdef FEAT_SESSION @@ -1770,7 +1771,7 @@ } if (checkforcmd(&ea.cmd, "browse", 3)) { -#ifdef FEAT_BROWSE +#ifdef FEAT_BROWSE_CMD cmdmod.browse = TRUE; #endif continue; @@ -2978,6 +2979,7 @@ {"keepmarks", 3, FALSE}, {"leftabove", 5, FALSE}, {"lockmarks", 3, FALSE}, + {"noautocmd", 3, FALSE}, {"rightbelow", 6, FALSE}, {"sandbox", 3, FALSE}, {"silent", 3, FALSE}, @@ -3608,6 +3610,7 @@ return set_context_in_autocmd(xp, arg, FALSE); case CMD_doautocmd: + case CMD_doautoall: return set_context_in_autocmd(xp, arg, TRUE); #endif case CMD_set: @@ -3680,6 +3683,11 @@ case CMD_highlight: set_context_in_highlight_cmd(xp, arg); break; +#ifdef FEAT_CSCOPE + case CMD_cscope: + set_context_in_cscope_cmd(xp, arg); + break; +#endif #ifdef FEAT_LISTCMDS case CMD_bdelete: case CMD_bwipeout: @@ -5121,7 +5129,11 @@ } vim_free(cmd->uc_rep); - cmd->uc_rep = 0; + cmd->uc_rep = NULL; +#if defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL) + vim_free(cmd->uc_compl_arg); + cmd->uc_compl_arg = NULL; +#endif break; } @@ -5180,6 +5192,9 @@ {EXPAND_AUGROUP, "augroup"}, {EXPAND_BUFFERS, "buffer"}, {EXPAND_COMMANDS, "command"}, +#if defined(FEAT_CSCOPE) + {EXPAND_CSCOPE, "cscope"}, +#endif #if defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL) {EXPAND_USER_DEFINED, "custom"}, {EXPAND_USER_LIST, "customlist"}, @@ -5479,6 +5494,9 @@ return OK; } +/* + * ":command ..." + */ static void ex_command(eap) exarg_T *eap; @@ -5910,7 +5928,8 @@ char_u *q; char_u *start; - char_u *end; + char_u *end = NULL; + char_u *ksp; size_t len, totlen; size_t split_len = 0; @@ -5927,16 +5946,51 @@ /* * Replace <> in the command by the arguments. + * First round: "buf" is NULL, compute length, allocate "buf". + * Second round: copy result into "buf". */ buf = NULL; for (;;) { - p = cmd->uc_rep; - q = buf; + p = cmd->uc_rep; /* source */ + q = buf; /* destination */ totlen = 0; - while ((start = vim_strchr(p, '<')) != NULL - && (end = vim_strchr(start + 1, '>')) != NULL) + + for (;;) { + start = vim_strchr(p, '<'); + if (start != NULL) + end = vim_strchr(start + 1, '>'); + if (buf != NULL) + { + ksp = vim_strchr(p, K_SPECIAL); + if (ksp != NULL && (start == NULL || ksp < start || end == NULL) + && ((ksp[1] == KS_SPECIAL && ksp[2] == KE_FILLER) +# ifdef FEAT_GUI + || (ksp[1] == KS_EXTRA && ksp[2] == (int)KE_CSI) +# endif + )) + { + /* K_SPECIAL han been put in the buffer as K_SPECIAL + * KS_SPECIAL KE_FILLER, like for mappings, but + * do_cmdline() doesn't handle that, so convert it back. + * Also change K_SPECIAL KS_EXTRA KE_CSI into CSI. */ + len = ksp - p; + if (len > 0) + { + mch_memmove(q, p, len); + q += len; + } + *q++ = ksp[1] == KS_SPECIAL ? K_SPECIAL : CSI; + p = ksp + 3; + continue; + } + } + + /* break if there no is found */ + if (start == NULL || end == NULL) + break; + /* Include the '>' */ ++end; @@ -7803,6 +7857,9 @@ { vim_free(prev_dir); prev_dir = NULL; + + vim_free(globaldir); + globaldir = NULL; } #endif @@ -7825,6 +7882,10 @@ else #endif { +#ifdef FEAT_AUTOCMD + if (allbuf_locked()) + return; +#endif if (vim_strchr(p_cpo, CPO_CHDIR) != NULL && curbufIsChanged() && !eap->forceit) { @@ -8749,8 +8810,8 @@ else if (*dirnow != NUL && (ssop_flags & SSOP_CURDIR) && globaldir != NULL) { - (void)mch_chdir((char *)globaldir); - shorten_fnames(TRUE); + if (mch_chdir((char *)globaldir) == 0) + shorten_fnames(TRUE); } failed |= (makeopens(fd, dirnow) == FAIL); @@ -9506,24 +9567,50 @@ break; } s = src + 1; + if (*s == '<') /* "#<99" uses v:oldfiles */ + ++s; i = (int)getdigits(&s); *usedlen = (int)(s - src); /* length of what we expand */ - buf = buflist_findnr(i); - if (buf == NULL) + if (src[1] == '<') { - *errormsg = (char_u *)_("E194: No alternate file name to substitute for '#'"); + if (*usedlen < 2) + { + /* Should we give an error message for #b_fname == NULL) + else { - result = (char_u *)""; - valid = 0; /* Must have ":p:h" to be valid */ + buf = buflist_findnr(i); + if (buf == NULL) + { + *errormsg = (char_u *)_("E194: No alternate file name to substitute for '#'"); + return NULL; + } + if (lnump != NULL) + *lnump = ECMD_LAST; + if (buf->b_fname == NULL) + { + result = (char_u *)""; + valid = 0; /* Must have ":p:h" to be valid */ + } + else + result = buf->b_fname; } - else - result = buf->b_fname; break; #ifdef FEAT_SEARCHPATH @@ -9541,6 +9628,15 @@ #ifdef FEAT_AUTOCMD case SPEC_AFILE: /* file name for autocommand */ result = autocmd_fname; + if (result != NULL && !autocmd_fname_full) + { + /* Still need to turn the fname into a full path. It is + * postponed to avoid a delay when is not used. */ + autocmd_fname_full = TRUE; + result = FullName_save(autocmd_fname, FALSE); + vim_free(autocmd_fname); + autocmd_fname = result; + } if (result == NULL) { *errormsg = (char_u *)_("E495: no autocommand file name to substitute for \"\""); @@ -10067,7 +10163,7 @@ */ if (put_line(fd, "let s:sx = expand(\":p:r\").\"x.vim\"") == FAIL || put_line(fd, "if file_readable(s:sx)") == FAIL - || put_line(fd, " exe \"source \" . s:sx") == FAIL + || put_line(fd, " exe \"source \" . fnameescape(s:sx)") == FAIL || put_line(fd, "endif") == FAIL) return FAIL; @@ -10689,7 +10785,8 @@ p_viminfo = (char_u *)"'100"; if (eap->cmdidx == CMD_rviminfo) { - if (read_viminfo(eap->arg, TRUE, TRUE, eap->forceit) == FAIL) + if (read_viminfo(eap->arg, VIF_WANT_INFO | VIF_WANT_MARKS + | (eap->forceit ? VIF_FORCEIT : 0)) == FAIL) EMSG(_("E195: Cannot open viminfo file for reading")); } else diff -Naur vim72.orig/src/ex_getln.c vim72/src/ex_getln.c --- vim72.orig/src/ex_getln.c 2008-08-08 02:31:33.000000000 -0700 +++ vim72/src/ex_getln.c 2009-03-22 21:32:51.512605113 -0700 @@ -31,6 +31,8 @@ int cmdattr; /* attributes for prompt */ int overstrike; /* Typing mode on the command line. Shared by getcmdline() and put_on_cmdline(). */ + expand_T *xpc; /* struct being used for expansion, xp_pattern + may point into cmdbuff */ int xp_context; /* type of expansion */ # ifdef FEAT_EVAL char_u *xp_arg; /* user-defined expansion arg */ @@ -38,7 +40,11 @@ # endif }; -static struct cmdline_info ccline; /* current cmdline_info */ +/* The current cmdline_info. It is initialized in getcmdline() and after that + * used by other functions. When invoking getcmdline() recursively it needs + * to be saved with save_cmdline() and restored with restore_cmdline(). + * TODO: make it local to getcmdline() and pass it around. */ +static struct cmdline_info ccline; static int cmd_showtail; /* Only show path tail in lists ? */ @@ -238,6 +244,7 @@ } ExpandInit(&xpc); + ccline.xpc = &xpc; #ifdef FEAT_RIGHTLEFT if (curwin->w_p_rl && *curwin->w_p_rlc == 's' @@ -408,9 +415,10 @@ #endif /* - * works like CTRL-P (unless 'wc' is ). + * When there are matching completions to select works like + * CTRL-P (unless 'wc' is ). */ - if (c != p_wc && c == K_S_TAB && xpc.xp_numfiles != -1) + if (c != p_wc && c == K_S_TAB && xpc.xp_numfiles > 0) c = Ctrl_P; #ifdef FEAT_WILDMENU @@ -1513,6 +1521,7 @@ int old_firstc; vim_free(ccline.cmdbuff); + xpc.xp_context = EXPAND_NOTHING; if (hiscnt == hislen) p = lookfor; /* back to the old one */ else @@ -1839,6 +1848,7 @@ #endif ExpandCleanup(&xpc); + ccline.xpc = NULL; #ifdef FEAT_SEARCH_EXTRA if (did_incsearch) @@ -1990,8 +2000,8 @@ #if defined(FEAT_AUTOCMD) || defined(PROTO) /* - * Check if "curbuf_lock" is set and return TRUE when it is and give an error - * message. + * Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is + * and give an error message. */ int curbuf_locked() @@ -2001,6 +2011,21 @@ EMSG(_("E788: Not allowed to edit another buffer now")); return TRUE; } + return allbuf_locked(); +} + +/* + * Check if "allbuf_lock" is set and return TRUE when it is and give an error + * message. + */ + int +allbuf_locked() +{ + if (allbuf_lock > 0) + { + EMSG(_("E811: Not allowed to change buffer information now")); + return TRUE; + } return FALSE; } #endif @@ -2508,6 +2533,20 @@ } mch_memmove(ccline.cmdbuff, p, (size_t)ccline.cmdlen + 1); vim_free(p); + + if (ccline.xpc != NULL + && ccline.xpc->xp_pattern != NULL + && ccline.xpc->xp_context != EXPAND_NOTHING + && ccline.xpc->xp_context != EXPAND_UNSUCCESSFUL) + { + int i = (int)(ccline.xpc->xp_pattern - p); + + /* If xp_pattern points inside the old cmdbuff it needs to be adjusted + * to point into the newly allocated memory. */ + if (i >= 0 && i <= ccline.cmdlen) + ccline.xpc->xp_pattern = ccline.cmdbuff + i; + } + return OK; } @@ -2875,6 +2914,7 @@ prev_ccline = ccline; ccline.cmdbuff = NULL; ccline.cmdprompt = NULL; + ccline.xpc = NULL; } /* @@ -3582,6 +3622,7 @@ ExpandInit(xp) expand_T *xp; { + xp->xp_pattern = NULL; xp->xp_backslash = XP_BS_NONE; #ifndef BACKSLASH_IN_FILENAME xp->xp_shell = FALSE; @@ -4477,6 +4518,9 @@ {EXPAND_EVENTS, get_event_name, TRUE}, {EXPAND_AUGROUP, get_augroup_name, TRUE}, #endif +#ifdef FEAT_CSCOPE + {EXPAND_CSCOPE, get_cscope_name, TRUE}, +#endif #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \ && (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE)) {EXPAND_LANGUAGE, get_lang_arg, TRUE}, @@ -4871,7 +4915,7 @@ if (s == NULL) return FAIL; sprintf((char *)s, "%s/%s*.vim", dirname, pat); - all = globpath(p_rtp, s); + all = globpath(p_rtp, s, 0); vim_free(s); if (all == NULL) return FAIL; @@ -4912,9 +4956,10 @@ * newlines. Returns NULL for an error or no matches. */ char_u * -globpath(path, file) +globpath(path, file, expand_options) char_u *path; char_u *file; + int expand_options; { expand_T xpc; char_u *buf; @@ -4943,10 +4988,10 @@ { add_pathsep(buf); STRCAT(buf, file); - if (ExpandFromContext(&xpc, buf, &num_p, &p, WILD_SILENT) != FAIL - && num_p > 0) + if (ExpandFromContext(&xpc, buf, &num_p, &p, + WILD_SILENT|expand_options) != FAIL && num_p > 0) { - ExpandEscape(&xpc, buf, num_p, p, WILD_SILENT); + ExpandEscape(&xpc, buf, num_p, p, WILD_SILENT|expand_options); for (len = 0, i = 0; i < num_p; ++i) len += (int)STRLEN(p[i]) + 1; @@ -6020,9 +6065,7 @@ # endif return K_IGNORE; } - cmdwin_type = ccline.cmdfirstc; - if (cmdwin_type == NUL) - cmdwin_type = '-'; + cmdwin_type = get_cmdline_type(); /* Create the command-line buffer empty. */ (void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE); @@ -6046,7 +6089,7 @@ /* Showing the prompt may have set need_wait_return, reset it. */ need_wait_return = FALSE; - histtype = hist_char2type(ccline.cmdfirstc); + histtype = hist_char2type(cmdwin_type); if (histtype == HIST_CMD || histtype == HIST_DEBUG) { if (p_wc == TAB) diff -Naur vim72.orig/src/feature.h vim72/src/feature.h --- vim72.orig/src/feature.h 2008-08-06 04:00:39.000000000 -0700 +++ vim72/src/feature.h 2009-03-22 21:28:12.894752340 -0700 @@ -767,9 +767,13 @@ /* * +browse ":browse" command. + * or just the ":browse" command modifier */ -#if defined(FEAT_NORMAL) && (defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)) -# define FEAT_BROWSE +#if defined(FEAT_NORMAL) +# define FEAT_BROWSE_CMD +# if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) +# define FEAT_BROWSE +# endif #endif /* diff -Naur vim72.orig/src/fileio.c vim72/src/fileio.c --- vim72.orig/src/fileio.c 2008-08-06 04:01:03.000000000 -0700 +++ vim72/src/fileio.c 2009-03-22 21:32:58.833074173 -0700 @@ -69,7 +69,7 @@ static int au_find_group __ARGS((char_u *name)); # define AUGROUP_DEFAULT -1 /* default autocmd group */ -# define AUGROUP_ERROR -2 /* errornouse autocmd group */ +# define AUGROUP_ERROR -2 /* erroneous autocmd group */ # define AUGROUP_ALL -3 /* all autocmd groups */ #endif @@ -144,7 +144,9 @@ # endif #endif static int move_lines __ARGS((buf_T *frombuf, buf_T *tobuf)); - +#ifdef FEAT_AUTOCMD +static char *e_auchangedbuf = N_("E812: Autocommands changed buffer or buffer name"); +#endif void filemess(buf, name, s, attr) @@ -295,6 +297,19 @@ int conv_restlen = 0; /* nr of bytes in conv_rest[] */ #endif +#ifdef FEAT_AUTOCMD + /* Remember the initial values of curbuf, curbuf->b_ffname and + * curbuf->b_fname to detect whether they are altered as a result of + * executing nasty autocommands. Also check if "fname" and "sfname" + * point to one of these values. */ + buf_T *old_curbuf = curbuf; + char_u *old_b_ffname = curbuf->b_ffname; + char_u *old_b_fname = curbuf->b_fname; + int using_b_ffname = (fname == curbuf->b_ffname) + || (sfname == curbuf->b_ffname); + int using_b_fname = (fname == curbuf->b_fname) + || (sfname == curbuf->b_fname); +#endif write_no_eol_lnum = 0; /* in case it was set by the previous read */ /* @@ -589,7 +604,21 @@ #ifdef FEAT_QUICKFIX if (!bt_dontwrite(curbuf)) #endif + { check_need_swap(newfile); +#ifdef FEAT_AUTOCMD + /* SwapExists autocommand may mess things up */ + if (curbuf != old_curbuf + || (using_b_ffname + && (old_b_ffname != curbuf->b_ffname)) + || (using_b_fname + && (old_b_fname != curbuf->b_fname))) + { + EMSG(_(e_auchangedbuf)); + return FAIL; + } +#endif + } if (dir_of_file_exists(fname)) filemess(curbuf, sfname, (char_u *)_("[New File]"), 0); else @@ -668,6 +697,17 @@ #endif { check_need_swap(newfile); +#ifdef FEAT_AUTOCMD + if (!read_stdin && (curbuf != old_curbuf + || (using_b_ffname && (old_b_ffname != curbuf->b_ffname)) + || (using_b_fname && (old_b_fname != curbuf->b_fname)))) + { + EMSG(_(e_auchangedbuf)); + if (!read_buffer) + close(fd); + return FAIL; + } +#endif #ifdef UNIX /* Set swap file protection bits after creating it. */ if (swap_mode > 0 && curbuf->b_ml.ml_mfp->mf_fname != NULL) @@ -698,7 +738,6 @@ { int m = msg_scroll; int n = msg_scrolled; - buf_T *old_curbuf = curbuf; /* * The file must be closed again, the autocommands may want to change @@ -740,8 +779,13 @@ /* * Don't allow the autocommands to change the current buffer. * Try to re-open the file. + * + * Don't allow the autocommands to change the buffer name either + * (cd for example) if it invalidates fname or sfname. */ if (!read_stdin && (curbuf != old_curbuf + || (using_b_ffname && (old_b_ffname != curbuf->b_ffname)) + || (using_b_fname && (old_b_fname != curbuf->b_fname)) || (fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) < 0)) { --no_wait_return; @@ -932,7 +976,10 @@ else { if (eap != NULL && eap->force_ff != 0) + { fileformat = get_fileformat_force(curbuf, eap); + try_unix = try_dos = try_mac = FALSE; + } else if (curbuf->b_p_bin) fileformat = EOL_UNIX; /* binary: use Unix format */ else if (*p_ffs == NUL) @@ -2211,7 +2258,7 @@ { /* Use stderr for stdin, makes shell commands work. */ close(0); - dup(2); + ignored = dup(2); } #endif @@ -2341,11 +2388,6 @@ STRCAT(IObuff, _("[CR missing]")); c = TRUE; } - if (ff_error == EOL_MAC) - { - STRCAT(IObuff, _("[NL found]")); - c = TRUE; - } if (split) { STRCAT(IObuff, _("[long lines split]")); @@ -2711,7 +2753,7 @@ { if (!curbuf->b_marks_read && get_viminfo_parameter('\'') > 0 && curbuf->b_ffname != NULL) - read_viminfo(NULL, FALSE, TRUE, FALSE); + read_viminfo(NULL, VIF_WANT_MARKS); /* Always set b_marks_read; needed when 'viminfo' is changed to include * the ' parameter after opening a buffer. */ @@ -3451,7 +3493,7 @@ { # ifdef UNIX # ifdef HAVE_FCHOWN - fchown(fd, st_old.st_uid, st_old.st_gid); + ignored = fchown(fd, st_old.st_uid, st_old.st_gid); # endif if (mch_stat((char *)IObuff, &st) < 0 || st.st_uid != st_old.st_uid @@ -4367,7 +4409,7 @@ || st.st_uid != st_old.st_uid || st.st_gid != st_old.st_gid) { - fchown(fd, st_old.st_uid, st_old.st_gid); + ignored = fchown(fd, st_old.st_uid, st_old.st_gid); if (perm >= 0) /* set permission again, may have changed */ (void)mch_setperm(wfname, perm); } @@ -5246,13 +5288,16 @@ /* Convert with iconv(). */ if (ip->bw_restlen > 0) { + char *fp; + /* Need to concatenate the remainder of the previous call and * the bytes of the current call. Use the end of the * conversion buffer for this. */ fromlen = len + ip->bw_restlen; - from = (char *)ip->bw_conv_buf + ip->bw_conv_buflen - fromlen; - mch_memmove((void *)from, ip->bw_rest, (size_t)ip->bw_restlen); - mch_memmove((void *)(from + ip->bw_restlen), buf, (size_t)len); + fp = (char *)ip->bw_conv_buf + ip->bw_conv_buflen - fromlen; + mch_memmove(fp, ip->bw_rest, (size_t)ip->bw_restlen); + mch_memmove(fp + ip->bw_restlen, buf, (size_t)len); + from = fp; tolen = ip->bw_conv_buflen - fromlen; } else @@ -5550,9 +5595,10 @@ name = "ucs-4le"; /* FF FE 00 00 */ len = 4; } - else if (flags == FIO_ALL || flags == (FIO_UCS2 | FIO_ENDIAN_L)) + else if (flags == (FIO_UCS2 | FIO_ENDIAN_L)) name = "ucs-2le"; /* FF FE */ - else if (flags == (FIO_UTF16 | FIO_ENDIAN_L)) + else if (flags == FIO_ALL || flags == (FIO_UTF16 | FIO_ENDIAN_L)) + /* utf-16le is preferred, it also works for ucs-2le text */ name = "utf-16le"; /* FF FE */ } else if (p[0] == 0xfe && p[1] == 0xff @@ -6031,9 +6077,9 @@ { tbuf[FGETS_SIZE - 2] = NUL; #ifdef USE_CR - fgets_cr((char *)tbuf, FGETS_SIZE, fp); + ignoredp = fgets_cr((char *)tbuf, FGETS_SIZE, fp); #else - fgets((char *)tbuf, FGETS_SIZE, fp); + ignoredp = fgets((char *)tbuf, FGETS_SIZE, fp); #endif } while (tbuf[FGETS_SIZE - 2] != NUL && tbuf[FGETS_SIZE - 2] != '\n'); } @@ -6107,12 +6153,24 @@ #ifdef HAVE_ACL vim_acl_T acl; /* ACL from original file */ #endif +#if defined(UNIX) || defined(CASE_INSENSITIVE_FILENAME) + int use_tmp_file = FALSE; +#endif /* - * When the names are identical, there is nothing to do. + * When the names are identical, there is nothing to do. When they refer + * to the same file (ignoring case and slash/backslash differences) but + * the file name differs we need to go through a temp file. */ if (fnamecmp(from, to) == 0) - return 0; + { +#ifdef CASE_INSENSITIVE_FILENAME + if (STRCMP(gettail(from), gettail(to)) != 0) + use_tmp_file = TRUE; + else +#endif + return 0; + } /* * Fail if the "from" file doesn't exist. Avoids that "to" is deleted. @@ -6120,6 +6178,55 @@ if (mch_stat((char *)from, &st) < 0) return -1; +#ifdef UNIX + { + struct stat st_to; + + /* It's possible for the source and destination to be the same file. + * This happens when "from" and "to" differ in case and are on a FAT32 + * filesystem. In that case go through a temp file name. */ + if (mch_stat((char *)to, &st_to) >= 0 + && st.st_dev == st_to.st_dev + && st.st_ino == st_to.st_ino) + use_tmp_file = TRUE; + } +#endif + +#if defined(UNIX) || defined(CASE_INSENSITIVE_FILENAME) + if (use_tmp_file) + { + char tempname[MAXPATHL + 1]; + + /* + * Find a name that doesn't exist and is in the same directory. + * Rename "from" to "tempname" and then rename "tempname" to "to". + */ + if (STRLEN(from) >= MAXPATHL - 5) + return -1; + STRCPY(tempname, from); + for (n = 123; n < 99999; ++n) + { + sprintf((char *)gettail((char_u *)tempname), "%d", n); + if (mch_stat(tempname, &st) < 0) + { + if (mch_rename((char *)from, tempname) == 0) + { + if (mch_rename(tempname, (char *)to) == 0) + return 0; + /* Strange, the second step failed. Try moving the + * file back and return failure. */ + mch_rename(tempname, (char *)from); + return -1; + } + /* If it fails for one temp name it will most likely fail + * for any temp name, give up. */ + return -1; + } + } + return -1; + } +#endif + /* * Delete the "to" file, this is required on some systems to make the * mch_rename() work, on other systems it makes sure that we don't have @@ -6260,7 +6367,7 @@ if (!stuff_empty() || global_busy || !typebuf_typed() #ifdef FEAT_AUTOCMD - || autocmd_busy || curbuf_lock > 0 + || autocmd_busy || curbuf_lock > 0 || allbuf_lock > 0 #endif ) need_check_timestamps = TRUE; /* check later */ @@ -6462,8 +6569,10 @@ set_vim_var_string(VV_FCS_REASON, (char_u *)reason, -1); set_vim_var_string(VV_FCS_CHOICE, (char_u *)"", -1); # endif + ++allbuf_lock; n = apply_autocmds(EVENT_FILECHANGEDSHELL, buf->b_fname, buf->b_fname, FALSE, buf); + --allbuf_lock; busy = FALSE; if (n) { @@ -6538,6 +6647,11 @@ tbuf = alloc((unsigned)(STRLEN(path) + STRLEN(mesg) + STRLEN(mesg2) + 2)); sprintf((char *)tbuf, mesg, path); +#ifdef FEAT_EVAL + /* Set warningmsg here, before the unimportant and output-specific + * mesg2 has been appended. */ + set_vim_var_string(VV_WARNINGMSG, tbuf, -1); +#endif #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG) if (can_reload) { @@ -8523,6 +8637,7 @@ char_u *save_sourcing_name; linenr_T save_sourcing_lnum; char_u *save_autocmd_fname; + int save_autocmd_fname_full; int save_autocmd_bufnr; char_u *save_autocmd_match; int save_autocmd_busy; @@ -8601,6 +8716,7 @@ * Save the autocmd_* variables and info about the current buffer. */ save_autocmd_fname = autocmd_fname; + save_autocmd_fname_full = autocmd_fname_full; save_autocmd_bufnr = autocmd_bufnr; save_autocmd_match = autocmd_match; save_autocmd_busy = autocmd_busy; @@ -8618,14 +8734,15 @@ if (fname != NULL && *fname != NUL) autocmd_fname = fname; else if (buf != NULL) - autocmd_fname = buf->b_fname; + autocmd_fname = buf->b_ffname; else autocmd_fname = NULL; } else autocmd_fname = fname_io; if (autocmd_fname != NULL) - autocmd_fname = FullName_save(autocmd_fname, FALSE); + autocmd_fname = vim_strsave(autocmd_fname); + autocmd_fname_full = FALSE; /* call FullName_save() later */ /* * Set the buffer number to be used for . @@ -8810,6 +8927,7 @@ sourcing_lnum = save_sourcing_lnum; vim_free(autocmd_fname); autocmd_fname = save_autocmd_fname; + autocmd_fname_full = save_autocmd_fname_full; autocmd_bufnr = save_autocmd_bufnr; autocmd_match = save_autocmd_match; #ifdef FEAT_EVAL @@ -8918,7 +9036,7 @@ { apc->curpat = NULL; - /* only use a pattern when it has not been removed, has commands and + /* Only use a pattern when it has not been removed, has commands and * the group matches. For buffer-local autocommands only check the * buffer number. */ if (ap->pat != NULL && ap->cmds != NULL @@ -9104,7 +9222,7 @@ set_context_in_autocmd(xp, arg, doautocmd) expand_T *xp; char_u *arg; - int doautocmd; /* TRUE for :doautocmd, FALSE for :autocmd */ + int doautocmd; /* TRUE for :doauto*, FALSE for :autocmd */ { char_u *p; int group; diff -Naur vim72.orig/src/fold.c vim72/src/fold.c --- vim72.orig/src/fold.c 2008-08-06 04:01:12.000000000 -0700 +++ vim72/src/fold.c 2009-03-22 21:30:10.950316246 -0700 @@ -48,7 +48,7 @@ static int foldFind __ARGS((garray_T *gap, linenr_T lnum, fold_T **fpp)); static int foldLevelWin __ARGS((win_T *wp, linenr_T lnum)); static void checkupdate __ARGS((win_T *wp)); -static void setFoldRepeat __ARGS((linenr_T lnum, long count, int open)); +static void setFoldRepeat __ARGS((linenr_T lnum, long count, int do_open)); static linenr_T setManualFold __ARGS((linenr_T lnum, int opening, int recurse, int *donep)); static linenr_T setManualFoldWin __ARGS((win_T *wp, linenr_T lnum, int opening, int recurse, int *donep)); static void foldOpenNested __ARGS((fold_T *fpr)); @@ -740,7 +740,7 @@ garray_T *found_ga; fold_T *found_fp = NULL; linenr_T found_off = 0; - int use_level = FALSE; + int use_level; int maybe_small = FALSE; int level = 0; linenr_T lnum = start; @@ -757,6 +757,7 @@ gap = &curwin->w_folds; found_ga = NULL; lnum_off = 0; + use_level = FALSE; for (;;) { if (!foldFind(gap, lnum - lnum_off, &fp)) @@ -783,20 +784,21 @@ else { lnum = found_fp->fd_top + found_fp->fd_len + found_off; - did_one = TRUE; if (foldmethodIsManual(curwin)) deleteFoldEntry(found_ga, (int)(found_fp - (fold_T *)found_ga->ga_data), recursive); else { - if (found_fp->fd_top + found_off < first_lnum) - first_lnum = found_fp->fd_top; - if (lnum > last_lnum) + if (first_lnum > found_fp->fd_top + found_off) + first_lnum = found_fp->fd_top + found_off; + if (last_lnum < lnum) last_lnum = lnum; - parseMarker(curwin); + if (!did_one) + parseMarker(curwin); deleteFoldMarkers(found_fp, recursive, found_off); } + did_one = TRUE; /* redraw window */ changed_window_setting(); @@ -811,6 +813,10 @@ redraw_curbuf_later(INVERTED); #endif } + else + /* Deleting markers may make cursor column invalid. */ + check_cursor_col(); + if (last_lnum > 0) changed_lines(first_lnum, (colnr_T)0, last_lnum, 0L); } @@ -1241,10 +1247,10 @@ * Repeat "count" times. */ static void -setFoldRepeat(lnum, count, open) +setFoldRepeat(lnum, count, do_open) linenr_T lnum; long count; - int open; + int do_open; { int done; long n; @@ -1252,7 +1258,7 @@ for (n = 0; n < count; ++n) { done = DONE_NOTHING; - (void)setManualFold(lnum, open, FALSE, &done); + (void)setManualFold(lnum, do_open, FALSE, &done); if (!(done & DONE_ACTION)) { /* Only give an error message when no fold could be opened. */ diff -Naur vim72.orig/src/getchar.c vim72/src/getchar.c --- vim72.orig/src/getchar.c 2008-07-22 09:57:48.000000000 -0700 +++ vim72/src/getchar.c 2009-03-22 21:32:01.425393770 -0700 @@ -3816,7 +3816,11 @@ int len = 1; if (msg_didout || msg_silent != 0) + { msg_putchar('\n'); + if (got_int) /* 'q' typed at MORE prompt */ + return; + } if ((mp->m_mode & (INSERT + CMDLINE)) == INSERT + CMDLINE) msg_putchar('!'); /* :map! */ else if (mp->m_mode & INSERT) @@ -4702,7 +4706,7 @@ return FAIL; if (mp->m_noremap != REMAP_YES && fprintf(fd, "nore") < 0) return FAIL; - if (fprintf(fd, cmd) < 0) + if (fputs(cmd, fd) < 0) return FAIL; if (buf != NULL && fputs(" ", fd) < 0) return FAIL; @@ -4801,7 +4805,7 @@ } if (IS_SPECIAL(c) || modifiers) /* special key */ { - if (fprintf(fd, (char *)get_special_key_name(c, modifiers)) < 0) + if (fputs((char *)get_special_key_name(c, modifiers), fd) < 0) return FAIL; continue; } diff -Naur vim72.orig/src/globals.h vim72/src/globals.h --- vim72.orig/src/globals.h 2008-07-26 04:53:29.000000000 -0700 +++ vim72/src/globals.h 2009-03-22 21:32:23.782828328 -0700 @@ -482,8 +482,10 @@ /* * While executing external commands or in Ex mode, should not insert GUI * events in the input buffer: Set hold_gui_events to non-zero. + * + * volatile because it is used in signal handler sig_sysmouse(). */ -EXTERN int hold_gui_events INIT(= 0); +EXTERN volatile int hold_gui_events INIT(= 0); /* * When resizing the shell is postponed, remember the new size, and call @@ -597,7 +599,8 @@ EXTERN int really_exiting INIT(= FALSE); /* TRUE when we are sure to exit, e.g., after * a deadly signal */ -EXTERN int full_screen INIT(= FALSE); +/* volatile because it is used in signal handler deathtrap(). */ +EXTERN volatile int full_screen INIT(= FALSE); /* TRUE when doing full-screen output * otherwise only writing some messages */ @@ -616,6 +619,11 @@ EXTERN int curbuf_lock INIT(= 0); /* non-zero when the current buffer can't be * changed. Used for FileChangedRO. */ +EXTERN int allbuf_lock INIT(= 0); + /* non-zero when no buffer name can be + * changed, no buffer can be deleted and + * current directory can't be changed. + * Used for SwapExists et al. */ #endif #ifdef FEAT_EVAL # define HAVE_SANDBOX @@ -739,10 +747,12 @@ */ EXTERN JMP_BUF lc_jump_env; /* argument to SETJMP() */ # ifdef SIGHASARG -EXTERN int lc_signal; /* catched signal number, 0 when no was signal - catched; used for mch_libcall() */ +/* volatile because it is used in signal handlers. */ +EXTERN volatile int lc_signal; /* caught signal number, 0 when no was signal + caught; used for mch_libcall() */ # endif -EXTERN int lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */ +/* volatile because it is used in signal handler deathtrap(). */ +EXTERN volatile int lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */ #endif #if defined(FEAT_MBYTE) || defined(FEAT_POSTSCRIPT) @@ -986,7 +996,8 @@ EXTERN FILE *scriptout INIT(= NULL); /* stream to write script to */ EXTERN int read_cmd_fd INIT(= 0); /* fd to read commands from */ -EXTERN int got_int INIT(= FALSE); /* set to TRUE when interrupt +/* volatile because it is used in signal handler catch_sigint(). */ +EXTERN volatile int got_int INIT(= FALSE); /* set to TRUE when interrupt signal occurred */ #ifdef USE_TERM_CONSOLE EXTERN int term_console INIT(= FALSE); /* set to TRUE when console used */ @@ -1022,6 +1033,7 @@ #endif #ifdef FEAT_AUTOCMD EXTERN char_u *autocmd_fname INIT(= NULL); /* fname for on cmdline */ +EXTERN int autocmd_fname_full; /* autocmd_fname is full path */ EXTERN int autocmd_bufnr INIT(= 0); /* fnum for on cmdline */ EXTERN char_u *autocmd_match INIT(= NULL); /* name for on cmdline */ EXTERN int did_cursorhold INIT(= FALSE); /* set when CursorHold t'gerd */ @@ -1339,7 +1351,6 @@ #ifdef FEAT_NETBEANS_INTG EXTERN char *netbeansArg INIT(= NULL); /* the -nb[:host:port:passwd] arg */ -EXTERN int netbeansCloseFile INIT(= 0); /* send killed if != 0 */ EXTERN int netbeansFireChanges INIT(= 1); /* send buffer changes if != 0 */ EXTERN int netbeansForcedQuit INIT(= 0);/* don't write modified files */ EXTERN int netbeansReadFile INIT(= 1); /* OK to read from disk if != 0 */ @@ -1548,6 +1559,14 @@ EXTERN time_t starttime; /* + * Some compilers warn for not using a return value, but in some situations we + * can't do anything useful with the value. Assign to this variable to avoid + * the warning. + */ +EXTERN int ignored; +EXTERN char *ignoredp; + +/* * Optional Farsi support. Include it here, so EXTERN and INIT are defined. */ #ifdef FEAT_FKMAP diff -Naur vim72.orig/src/gui_at_sb.c vim72/src/gui_at_sb.c --- vim72.orig/src/gui_at_sb.c 2004-06-07 07:32:25.000000000 -0700 +++ vim72/src/gui_at_sb.c 2009-03-22 21:29:14.042669926 -0700 @@ -1078,6 +1078,12 @@ Cardinal *num_params; /* unused */ { ScrollbarWidget sbw = (ScrollbarWidget)w; + /* Use a union to avoid a warning for the weird conversion from float to + * XtPointer. Comes from Xaw/Scrollbar.c. */ + union { + XtPointer xtp; + float xtf; + } xtpf; if (LookAhead(w, event)) return; @@ -1085,7 +1091,8 @@ /* thumbProc is not pretty, but is necessary for backwards compatibility on those architectures for which it work{s,ed}; the intent is to pass a (truncated) float by value. */ - XtCallCallbacks(w, XtNthumbProc, *(XtPointer*)&sbw->scrollbar.top); + xtpf.xtf = sbw->scrollbar.top; + XtCallCallbacks(w, XtNthumbProc, xtpf.xtp); XtCallCallbacks(w, XtNjumpProc, (XtPointer)&sbw->scrollbar.top); } diff -Naur vim72.orig/src/gui_beval.c vim72/src/gui_beval.c --- vim72.orig/src/gui_beval.c 2007-05-07 12:33:41.000000000 -0700 +++ vim72/src/gui_beval.c 2009-03-22 21:32:48.872435816 -0700 @@ -1291,6 +1291,23 @@ XtNy, ty, NULL); #endif + /* Set tooltip colors */ + { + Arg args[2]; + +#ifdef FEAT_GUI_MOTIF + args[0].name = XmNbackground; + args[0].value = gui.tooltip_bg_pixel; + args[1].name = XmNforeground; + args[1].value = gui.tooltip_fg_pixel; +#else /* Athena */ + args[0].name = XtNbackground; + args[0].value = gui.tooltip_bg_pixel; + args[1].name = XtNforeground; + args[1].value = gui.tooltip_fg_pixel; +#endif + XtSetValues(beval->balloonLabel, &args[0], XtNumber(args)); + } XtPopup(beval->balloonShell, XtGrabNone); diff -Naur vim72.orig/src/gui.c vim72/src/gui.c --- vim72.orig/src/gui.c 2008-07-27 12:32:14.000000000 -0700 +++ vim72/src/gui.c 2009-03-22 21:29:38.972265680 -0700 @@ -139,7 +139,7 @@ /* The read returns when the child closes the pipe (or when * the child dies for some reason). */ close(pipefd[1]); - (void)read(pipefd[0], &dummy, (size_t)1); + ignored = (int)read(pipefd[0], &dummy, (size_t)1); close(pipefd[0]); } @@ -3241,7 +3241,7 @@ i = Rows; gui_update_tabline(); Rows = i; - need_set_size = RESIZE_VERT; + need_set_size |= RESIZE_VERT; if (using_tabline) fix_size = TRUE; if (!gui_use_tabline()) @@ -3275,9 +3275,9 @@ if (gui.which_scrollbars[i] != prev_which_scrollbars[i]) { if (i == SBAR_BOTTOM) - need_set_size = RESIZE_VERT; + need_set_size |= RESIZE_VERT; else - need_set_size = RESIZE_HOR; + need_set_size |= RESIZE_HOR; if (gui.which_scrollbars[i]) fix_size = TRUE; } @@ -3297,7 +3297,7 @@ gui_mch_enable_menu(gui.menu_is_active); Rows = i; prev_menu_is_active = gui.menu_is_active; - need_set_size = RESIZE_VERT; + need_set_size |= RESIZE_VERT; if (gui.menu_is_active) fix_size = TRUE; } @@ -3308,7 +3308,7 @@ { gui_mch_show_toolbar(using_toolbar); prev_toolbar = using_toolbar; - need_set_size = RESIZE_VERT; + need_set_size |= RESIZE_VERT; if (using_toolbar) fix_size = TRUE; } @@ -3318,7 +3318,7 @@ { gui_mch_enable_footer(using_footer); prev_footer = using_footer; - need_set_size = RESIZE_VERT; + need_set_size |= RESIZE_VERT; if (using_footer) fix_size = TRUE; } @@ -3330,10 +3330,11 @@ prev_tearoff = using_tearoff; } #endif - if (need_set_size) + if (need_set_size != 0) { #ifdef FEAT_GUI_GTK - long c = Columns; + long prev_Columns = Columns; + long prev_Rows = Rows; #endif /* Adjust the size of the window to make the text area keep the * same size and to avoid that part of our window is off-screen @@ -3349,11 +3350,14 @@ * If you remove this, please test this command for resizing * effects (with optional left scrollbar): ":vsp|q|vsp|q|vsp|q". * Don't do this while starting up though. - * And don't change Rows, it may have be reduced intentionally - * when adding menu/toolbar/tabline. */ - if (!gui.starting) + * Don't change Rows when adding menu/toolbar/tabline. + * Don't change Columns when adding vertical toolbar. */ + if (!gui.starting && need_set_size != (RESIZE_VERT | RESIZE_HOR)) (void)char_avail(); - Columns = c; + if ((need_set_size & RESIZE_VERT) == 0) + Rows = prev_Rows; + if ((need_set_size & RESIZE_HOR) == 0) + Columns = prev_Columns; #endif } #ifdef FEAT_WINDOWS diff -Naur vim72.orig/src/gui_gtk_x11.c vim72/src/gui_gtk_x11.c --- vim72.orig/src/gui_gtk_x11.c 2008-07-04 03:46:24.000000000 -0700 +++ vim72/src/gui_gtk_x11.c 2009-03-22 21:29:14.042669926 -0700 @@ -4070,14 +4070,14 @@ if (mask & (XValue | YValue)) { - int w, h; - gui_mch_get_screen_dimensions(&w, &h); - h += p_ghr + get_menu_tool_height(); - w += get_menu_tool_width(); + int ww, hh; + gui_mch_get_screen_dimensions(&ww, &hh); + hh += p_ghr + get_menu_tool_height(); + ww += get_menu_tool_width(); if (mask & XNegative) - x += w - pixel_width; + x += ww - pixel_width; if (mask & YNegative) - y += h - pixel_height; + y += hh - pixel_height; #ifdef HAVE_GTK2 gtk_window_move(GTK_WINDOW(gui.mainwin), x, y); #else diff -Naur vim72.orig/src/gui_x11.c vim72/src/gui_x11.c --- vim72.orig/src/gui_x11.c 2008-06-08 08:13:45.000000000 -0700 +++ vim72/src/gui_x11.c 2009-03-22 21:32:06.281706663 -0700 @@ -1587,6 +1587,8 @@ XtCloseDisplay(gui.dpy); gui.dpy = NULL; vimShell = (Widget)0; + vim_free(gui_argv); + gui_argv = NULL; } /* @@ -1761,6 +1763,8 @@ * says that this isn't needed when exiting, so just skip it. */ XtCloseDisplay(gui.dpy); #endif + vim_free(gui_argv); + gui_argv = NULL; } /* @@ -2450,7 +2454,7 @@ *colorPtr = colortable[closest]; } - free(colortable); + vim_free(colortable); return OK; } @@ -3439,47 +3443,37 @@ char_u *signfile; { XpmAttributes attrs; - XImage *sign; + XImage *sign = NULL; int status; /* * Setup the color substitution table. */ - sign = NULL; if (signfile[0] != NUL && signfile[0] != '-') { - sign = (XImage *)alloc(sizeof(XImage)); - if (sign != NULL) + XpmColorSymbol color[5] = { - XpmColorSymbol color[5] = - { - {"none", NULL, 0}, - {"iconColor1", NULL, 0}, - {"bottomShadowColor", NULL, 0}, - {"topShadowColor", NULL, 0}, - {"selectColor", NULL, 0} - }; - attrs.valuemask = XpmColorSymbols; - attrs.numsymbols = 2; - attrs.colorsymbols = color; - attrs.colorsymbols[0].pixel = gui.back_pixel; - attrs.colorsymbols[1].pixel = gui.norm_pixel; - status = XpmReadFileToImage(gui.dpy, (char *)signfile, + {"none", NULL, 0}, + {"iconColor1", NULL, 0}, + {"bottomShadowColor", NULL, 0}, + {"topShadowColor", NULL, 0}, + {"selectColor", NULL, 0} + }; + attrs.valuemask = XpmColorSymbols; + attrs.numsymbols = 2; + attrs.colorsymbols = color; + attrs.colorsymbols[0].pixel = gui.back_pixel; + attrs.colorsymbols[1].pixel = gui.norm_pixel; + status = XpmReadFileToImage(gui.dpy, (char *)signfile, &sign, NULL, &attrs); - - if (status == 0) - { - /* Sign width is fixed at two columns now. - if (sign->width > gui.sign_width) - gui.sign_width = sign->width + 8; */ - } - else - { - vim_free(sign); - sign = NULL; - EMSG(_(e_signdata)); - } + if (status == 0) + { + /* Sign width is fixed at two columns now. + if (sign->width > gui.sign_width) + gui.sign_width = sign->width + 8; */ } + else + EMSG(_(e_signdata)); } return (void *)sign; @@ -3489,8 +3483,7 @@ gui_mch_destroy_sign(sign) void *sign; { - XFree(((XImage *)sign)->data); - vim_free(sign); + XDestroyImage((XImage*)sign); } #endif diff -Naur vim72.orig/src/gui_xmdlg.c vim72/src/gui_xmdlg.c --- vim72.orig/src/gui_xmdlg.c 2008-06-21 09:05:32.000000000 -0700 +++ vim72/src/gui_xmdlg.c 2009-03-22 21:29:14.042669926 -0700 @@ -369,10 +369,10 @@ char buf[TEMP_BUF_SIZE]; XmString items[MAX_ENTRIES_IN_LIST]; int i; - int index; + int idx; - for (index = (int)ENCODING; index < (int)NONE; ++index) - count[index] = 0; + for (idx = (int)ENCODING; idx < (int)NONE; ++idx) + count[idx] = 0; /* First we insert the wild char into every single list. */ if (fix != ENCODING) @@ -503,14 +503,14 @@ /* * Now loop trough the remaining lists and set them up. */ - for (index = (int)NAME; index < (int)NONE; ++index) + for (idx = (int)NAME; idx < (int)NONE; ++idx) { Widget w; - if (fix == (enum ListSpecifier)index) + if (fix == (enum ListSpecifier)idx) continue; - switch ((enum ListSpecifier)index) + switch ((enum ListSpecifier)idx) { case NAME: w = data->list[NAME]; @@ -525,21 +525,21 @@ w = (Widget)0; /* for lint */ } - for (i = 0; i < count[index]; ++i) + for (i = 0; i < count[idx]; ++i) { - items[i] = XmStringCreateLocalized(list[index][i]); - XtFree(list[index][i]); + items[i] = XmStringCreateLocalized(list[idx][i]); + XtFree(list[idx][i]); } XmListDeleteAllItems(w); - XmListAddItems(w, items, count[index], 1); - if (data->sel[index]) + XmListAddItems(w, items, count[idx], 1); + if (data->sel[idx]) { XmStringFree(items[0]); - items[0] = XmStringCreateLocalized(data->sel[index]); + items[0] = XmStringCreateLocalized(data->sel[idx]); XmListSelectItem(w, items[0], False); XmListSetBottomItem(w, items[0]); } - for (i = 0; i < count[index]; ++i) + for (i = 0; i < count[idx]; ++i) XmStringFree(items[i]); } } @@ -695,14 +695,14 @@ int n; XmString str; Arg args[4]; - char *msg = _("no specific match"); + char *nomatch_msg = _("no specific match"); n = 0; - str = XmStringCreateLocalized(msg); + str = XmStringCreateLocalized(nomatch_msg); XtSetArg(args[n], XmNlabelString, str); ++n; XtSetValues(data->sample, args, n); apply_fontlist(data->sample); - XmTextSetString(data->name, msg); + XmTextSetString(data->name, nomatch_msg); XmStringFree(str); return False; @@ -886,21 +886,21 @@ { int i; int max; - int index = 0; + int idx = 0; int size; - char str[128]; + char buf[128]; for (i = 0, max = 0; i < data->num; i++) { - get_part(fn(data, i), 7, str); - size = atoi(str); + get_part(fn(data, i), 7, buf); + size = atoi(buf); if ((size > max) && (size < MAX_DISPLAY_SIZE)) { - index = i; + idx = i; max = size; } } - strcpy(big_font, fn(data, index)); + strcpy(big_font, fn(data, idx)); } data->old = XLoadQueryFont(XtDisplay(parent), big_font); data->old_list = gui_motif_create_fontlist(data->old); @@ -1217,28 +1217,28 @@ if (i != 0) { - char name[TEMP_BUF_SIZE]; - char style[TEMP_BUF_SIZE]; - char size[TEMP_BUF_SIZE]; - char encoding[TEMP_BUF_SIZE]; + char namebuf[TEMP_BUF_SIZE]; + char stylebuf[TEMP_BUF_SIZE]; + char sizebuf[TEMP_BUF_SIZE]; + char encodingbuf[TEMP_BUF_SIZE]; char *found; found = names[0]; - name_part(found, name); - style_part(found, style); - size_part(found, size, data->in_pixels); - encoding_part(found, encoding); - - if (strlen(name) > 0 - && strlen(style) > 0 - && strlen(size) > 0 - && strlen(encoding) > 0) + name_part(found, namebuf); + style_part(found, stylebuf); + size_part(found, sizebuf, data->in_pixels); + encoding_part(found, encodingbuf); + + if (strlen(namebuf) > 0 + && strlen(stylebuf) > 0 + && strlen(sizebuf) > 0 + && strlen(encodingbuf) > 0) { - data->sel[NAME] = XtNewString(name); - data->sel[STYLE] = XtNewString(style); - data->sel[SIZE] = XtNewString(size); - data->sel[ENCODING] = XtNewString(encoding); + data->sel[NAME] = XtNewString(namebuf); + data->sel[STYLE] = XtNewString(stylebuf); + data->sel[SIZE] = XtNewString(sizebuf); + data->sel[ENCODING] = XtNewString(encodingbuf); data->font_name = XtNewString(names[0]); display_sample(data); XmTextSetString(data->name, data->font_name); diff -Naur vim72.orig/src/gui_xmebw.c vim72/src/gui_xmebw.c --- vim72.orig/src/gui_xmebw.c 2007-09-06 03:57:51.000000000 -0700 +++ vim72/src/gui_xmebw.c 2009-03-22 21:29:14.042669926 -0700 @@ -1256,7 +1256,7 @@ } else { - int adjust = 0; + adjust = 0; #if !defined(LESSTIF_VERSION) && (XmVersion > 1002) /* @@ -1268,12 +1268,11 @@ { case XmEXTERNAL_HIGHLIGHT: adjust = (eb->primitive.highlight_thickness - - (eb->pushbutton.default_button_shadow_thickness ? - Xm3D_ENHANCE_PIXEL : 0)); + (eb->pushbutton.default_button_shadow_thickness + ? Xm3D_ENHANCE_PIXEL : 0)); break; case XmINTERNAL_HIGHLIGHT: - adjust = 0; break; default: diff -Naur vim72.orig/src/if_cscope.c vim72/src/if_cscope.c --- vim72.orig/src/if_cscope.c 2008-06-24 09:32:34.000000000 -0700 +++ vim72/src/if_cscope.c 2009-03-22 21:32:56.384915491 -0700 @@ -74,7 +74,7 @@ { "add", cs_add, N_("Add a new database"), "add file|dir [pre-path] [flags]", 0 }, { "find", cs_find, - N_("Query for a pattern"), FIND_USAGE, 1 }, + N_("Query for a pattern"), "find c|d|e|f|g|i|s|t name", 1 }, { "help", cs_help, N_("Show this message"), "help", 0 }, { "kill", cs_kill, @@ -93,12 +93,117 @@ (void)EMSG2(_("E560: Usage: cs[cope] %s"), cs_cmds[(int)x].usage); } +#if defined(FEAT_CMDL_COMPL) || defined(PROTO) + +static enum +{ + EXP_CSCOPE_SUBCMD, /* expand ":cscope" sub-commands */ + EXP_CSCOPE_FIND, /* expand ":cscope find" arguments */ + EXP_CSCOPE_KILL /* expand ":cscope kill" arguments */ +} expand_what; + +/* + * Function given to ExpandGeneric() to obtain the cscope command + * expansion. + */ +/*ARGSUSED*/ + char_u * +get_cscope_name(xp, idx) + expand_T *xp; + int idx; +{ + switch (expand_what) + { + case EXP_CSCOPE_SUBCMD: + /* Complete with sub-commands of ":cscope": + * add, find, help, kill, reset, show */ + return (char_u *)cs_cmds[idx].name; + case EXP_CSCOPE_FIND: + { + const char *query_type[] = + { + "c", "d", "e", "f", "g", "i", "s", "t", NULL + }; + + /* Complete with query type of ":cscope find {query_type}". + * {query_type} can be letters (c, d, ... t) or numbers (0, 1, + * ..., 8) but only complete with letters, since numbers are + * redundant. */ + return (char_u *)query_type[idx]; + } + case EXP_CSCOPE_KILL: + { + int i; + int current_idx = 0; + static char_u connection[2]; + + /* ":cscope kill" accepts connection numbers or partial names of + * the pathname of the cscope database as argument. Only complete + * with connection numbers. -1 can also be used to kill all + * connections. */ + for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) + { + if (csinfo[i].fname == NULL) + continue; + if (current_idx++ == idx) + { + /* Connection number fits in one character since + * CSCOPE_MAX_CONNECTIONS is < 10 */ + connection[0] = i + '0'; + connection[1] = NUL; + return connection; + } + } + return (current_idx == idx && idx > 0) ? (char_u *)"-1" : NULL; + } + default: + return NULL; + } +} + +/* + * Handle command line completion for :cscope command. + */ + void +set_context_in_cscope_cmd(xp, arg) + expand_T *xp; + char_u *arg; +{ + char_u *p; + + /* Default: expand subcommands */ + xp->xp_context = EXPAND_CSCOPE; + expand_what = EXP_CSCOPE_SUBCMD; + xp->xp_pattern = arg; + + /* (part of) subcommand already typed */ + if (*arg != NUL) + { + p = skiptowhite(arg); + if (*p != NUL) /* past first word */ + { + xp->xp_pattern = skipwhite(p); + if (*skiptowhite(xp->xp_pattern) != NUL) + xp->xp_context = EXPAND_NOTHING; + else if (STRNICMP(arg, "add", p - arg) == 0) + xp->xp_context = EXPAND_FILES; + else if (STRNICMP(arg, "kill", p - arg) == 0) + expand_what = EXP_CSCOPE_KILL; + else if (STRNICMP(arg, "find", p - arg) == 0) + expand_what = EXP_CSCOPE_FIND; + else + xp->xp_context = EXPAND_NOTHING; + } + } +} + +#endif /* FEAT_CMDL_COMPL */ + /* * PRIVATE: do_cscope_general * - * find the command, print help if invalid, and the then call the - * corresponding command function, - * called from do_cscope and do_scscope + * Find the command, print help if invalid, and then call the corresponding + * command function. */ static void do_cscope_general(eap, make_split) @@ -659,6 +764,7 @@ { char *cmd; short search; + char *pat; switch (csoption[0]) { @@ -692,10 +798,17 @@ return NULL; } - if ((cmd = (char *)alloc((unsigned)(strlen(pattern) + 2))) == NULL) + /* Skip white space before the patter, except for text and pattern search, + * they may want to use the leading white space. */ + pat = pattern; + if (search != 4 && search != 6) + while vim_iswhite(*pat) + ++pat; + + if ((cmd = (char *)alloc((unsigned)(strlen(pat) + 2))) == NULL) return NULL; - (void)sprintf(cmd, "%d%s", search, pattern); + (void)sprintf(cmd, "%d%s", search, pat); return cmd; } /* cs_create_cmd */ @@ -1177,10 +1290,27 @@ (void)MSG_PUTS(_("cscope commands:\n")); while (cmdp->name != NULL) { - (void)smsg((char_u *)_("%-5s: %-30s (Usage: %s)"), - cmdp->name, _(cmdp->help), cmdp->usage); + char *help = _(cmdp->help); + int space_cnt = 30 - vim_strsize((char_u *)help); + + /* Use %*s rather than %30s to ensure proper alignment in utf-8 */ + if (space_cnt < 0) + space_cnt = 0; + (void)smsg((char_u *)_("%-5s: %s%*s (Usage: %s)"), + cmdp->name, + help, space_cnt, " ", + cmdp->usage); if (strcmp(cmdp->name, "find") == 0) - MSG_PUTS(FIND_HELP); + MSG_PUTS(_("\n" + " c: Find functions calling this function\n" + " d: Find functions called by this function\n" + " e: Find this egrep pattern\n" + " f: Find this file\n" + " g: Find this definition\n" + " i: Find files #including this file\n" + " s: Find this C symbol\n" + " t: Find assignments to\n")); + cmdp++; } diff -Naur vim72.orig/src/if_cscope.h vim72/src/if_cscope.h --- vim72.orig/src/if_cscope.h 2007-09-02 07:51:08.000000000 -0700 +++ vim72/src/if_cscope.h 2009-03-22 21:27:04.882391674 -0700 @@ -42,17 +42,6 @@ * f 7name Find this file * i 8name Find files #including this file */ -#define FIND_USAGE "find c|d|e|f|g|i|s|t name" -#define FIND_HELP "\n\ - c: Find functions calling this function\n\ - d: Find functions called by this function\n\ - e: Find this egrep pattern\n\ - f: Find this file\n\ - g: Find this definition\n\ - i: Find files #including this file\n\ - s: Find this C symbol\n\ - t: Find assignments to\n" - typedef struct { char * name; diff -Naur vim72.orig/src/if_perl.xs vim72/src/if_perl.xs --- vim72.orig/src/if_perl.xs 2008-07-17 13:55:09.000000000 -0700 +++ vim72/src/if_perl.xs 2009-03-22 21:29:34.075951949 -0700 @@ -136,6 +136,9 @@ # define Perl_newXS_flags dll_Perl_newXS_flags #endif # define Perl_sv_free dll_Perl_sv_free +# if (PERL_REVISION == 5) && (PERL_VERSION >= 10) +# define Perl_sv_free2 dll_Perl_sv_free2 +# endif # define Perl_sv_isa dll_Perl_sv_isa # define Perl_sv_magic dll_Perl_sv_magic # define Perl_sv_setiv dll_Perl_sv_setiv @@ -163,7 +166,7 @@ # define Perl_Isv_yes_ptr dll_Perl_Isv_yes_ptr # define boot_DynaLoader dll_boot_DynaLoader -# define Perl_sys_init3 dll_Perl_sys_init3 +# define Perl_sys_init dll_Perl_sys_init # define Perl_sys_term dll_Perl_sys_term # define Perl_ISv_ptr dll_Perl_ISv_ptr # define Perl_Istack_max_ptr dll_Perl_Istack_max_ptr @@ -268,7 +271,8 @@ static void (*boot_DynaLoader)_((pTHX_ CV*)); #if (PERL_REVISION == 5) && (PERL_VERSION >= 10) -static void (*Perl_sys_init3)(int* argc, char*** argv, char*** env); +static void (*Perl_sv_free2)(pTHX_ SV*); +static void (*Perl_sys_init)(int* argc, char*** argv); static void (*Perl_sys_term)(void); static SV** (*Perl_ISv_ptr)(register PerlInterpreter*); static SV*** (*Perl_Istack_max_ptr)(register PerlInterpreter*); @@ -367,7 +371,8 @@ {"Perl_TXpv_ptr", (PERL_PROC*)&Perl_TXpv_ptr}, {"Perl_Tna_ptr", (PERL_PROC*)&Perl_Tna_ptr}, #else - {"Perl_sys_init3", (PERL_PROC*)&Perl_sys_init3}, + {"Perl_sv_free2", (PERL_PROC*)&Perl_sv_free2}, + {"Perl_sys_init", (PERL_PROC*)&Perl_sys_init}, {"Perl_sys_term", (PERL_PROC*)&Perl_sys_term}, {"Perl_ISv_ptr", (PERL_PROC*)&Perl_ISv_ptr}, {"Perl_Istack_sp_ptr", (PERL_PROC*)&Perl_Istack_sp_ptr}, @@ -455,7 +460,7 @@ static char *argv[] = { "", "-e", "" }; #if (PERL_REVISION == 5) && (PERL_VERSION >= 10) - Perl_sys_init3(&argc, (char***)&argv, NULL); + Perl_sys_init(&argc, (char***)&argv); #endif perl_interp = perl_alloc(); perl_construct(perl_interp); diff -Naur vim72.orig/src/if_python.c vim72/src/if_python.c --- vim72.orig/src/if_python.c 2008-07-17 14:09:32.000000000 -0700 +++ vim72/src/if_python.c 2009-03-22 21:30:25.899274200 -0700 @@ -531,6 +531,12 @@ if (PythonMod_Init()) goto fail; + /* Remove the element from sys.path that was added because of our + * argv[0] value in PythonMod_Init(). Previously we used an empty + * string, but dependinding on the OS we then get an empty entry or + * the current directory in sys.path. */ + PyRun_SimpleString("import sys; sys.path = filter(lambda x: x != '/must>not&exist', sys.path)"); + /* the first python thread is vim's, release the lock */ Python_SaveThread(); @@ -1145,14 +1151,23 @@ /* Check if we run into a recursive loop. The item must be in lookupDict * then and we can use it again. */ - sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U, (long_u)our_tv); - result = PyDict_GetItemString(lookupDict, ptrBuf); - if (result != NULL) - Py_INCREF(result); - else if (our_tv->v_type == VAR_STRING) + if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL) + || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL)) + { + sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U, + our_tv->v_type == VAR_LIST ? (long_u)our_tv->vval.v_list + : (long_u)our_tv->vval.v_dict); + result = PyDict_GetItemString(lookupDict, ptrBuf); + if (result != NULL) + { + Py_INCREF(result); + return result; + } + } + + if (our_tv->v_type == VAR_STRING) { result = Py_BuildValue("s", our_tv->vval.v_string); - PyDict_SetItemString(lookupDict, ptrBuf, result); } else if (our_tv->v_type == VAR_NUMBER) { @@ -1161,7 +1176,6 @@ /* For backwards compatibility numbers are stored as strings. */ sprintf(buf, "%ld", (long)our_tv->vval.v_number); result = Py_BuildValue("s", buf); - PyDict_SetItemString(lookupDict, ptrBuf, result); } # ifdef FEAT_FLOAT else if (our_tv->v_type == VAR_FLOAT) @@ -1170,7 +1184,6 @@ sprintf(buf, "%f", our_tv->vval.v_float); result = Py_BuildValue("s", buf); - PyDict_SetItemString(lookupDict, ptrBuf, result); } # endif else if (our_tv->v_type == VAR_LIST) @@ -1179,10 +1192,11 @@ listitem_T *curr; result = PyList_New(0); - PyDict_SetItemString(lookupDict, ptrBuf, result); if (list != NULL) { + PyDict_SetItemString(lookupDict, ptrBuf, result); + for (curr = list->lv_first; curr != NULL; curr = curr->li_next) { newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict); @@ -1194,7 +1208,6 @@ else if (our_tv->v_type == VAR_DICT) { result = PyDict_New(); - PyDict_SetItemString(lookupDict, ptrBuf, result); if (our_tv->vval.v_dict != NULL) { @@ -1203,6 +1216,8 @@ hashitem_T *hi; dictitem_T *di; + PyDict_SetItemString(lookupDict, ptrBuf, result); + for (hi = ht->ht_array; todo > 0; ++hi) { if (!HASHITEM_EMPTY(hi)) @@ -2345,7 +2360,8 @@ { PyObject *mod; PyObject *dict; - static char *(argv[2]) = {"", NULL}; + /* The special value is removed from sys.path in Python_Init(). */ + static char *(argv[2]) = {"/must>not&exist/foo", NULL}; /* Fixups... */ BufferType.ob_type = &PyType_Type; diff -Naur vim72.orig/src/if_xcmdsrv.c vim72/src/if_xcmdsrv.c --- vim72.orig/src/if_xcmdsrv.c 2008-07-18 06:05:03.000000000 -0700 +++ vim72/src/if_xcmdsrv.c 2009-03-22 21:28:30.191858640 -0700 @@ -736,7 +736,7 @@ + serverReply.ga_len; e.id = w; ga_init2(&e.strings, 1, 100); - memcpy(p, &e, sizeof(e)); + mch_memmove(p, &e, sizeof(e)); serverReply.ga_len++; } } @@ -1018,7 +1018,7 @@ p++; count = numItems - (p - regProp); if (count > 0) - memcpy(entry, p, count); + mch_memmove(entry, p, count); XChangeProperty(dpy, RootWindow(dpy, 0), registryProperty, XA_STRING, 8, PropModeReplace, regProp, (int)(numItems - (p - entry))); @@ -1072,7 +1072,7 @@ p++; lastHalf = numItems - (p - regProp); if (lastHalf > 0) - memcpy(entry, p, lastHalf); + mch_memmove(entry, p, lastHalf); numItems = (entry - regProp) + lastHalf; p = entry; continue; diff -Naur vim72.orig/src/macros.h vim72/src/macros.h --- vim72.orig/src/macros.h 2007-08-04 04:44:18.000000000 -0700 +++ vim72/src/macros.h 2009-03-22 21:31:27.235204917 -0700 @@ -127,15 +127,31 @@ #ifdef FEAT_LANGMAP /* * Adjust chars in a language according to 'langmap' option. - * NOTE that there is NO overhead if 'langmap' is not set; but even - * when set we only have to do 2 ifs and an array lookup. + * NOTE that there is no noticeable overhead if 'langmap' is not set. + * When set the overhead for characters < 256 is small. * Don't apply 'langmap' if the character comes from the Stuff buffer. * The do-while is just to ignore a ';' after the macro. */ -# define LANGMAP_ADJUST(c, condition) do { \ - if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0 && (c) < 256) \ - c = langmap_mapchar[c]; \ +# ifdef FEAT_MBYTE +# define LANGMAP_ADJUST(c, condition) \ + do { \ + if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0) \ + { \ + if ((c) < 256) \ + c = langmap_mapchar[c]; \ + else \ + c = langmap_adjust_mb(c); \ + } \ } while (0) +# else +# define LANGMAP_ADJUST(c, condition) \ + do { \ + if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0 && (c) < 256) \ + c = langmap_mapchar[c]; \ + } while (0) +# endif +#else +# define LANGMAP_ADJUST(c, condition) /* nop */ #endif /* diff -Naur vim72.orig/src/main.c vim72/src/main.c --- vim72.orig/src/main.c 2008-07-24 01:40:56.000000000 -0700 +++ vim72/src/main.c 2009-03-22 21:29:14.046670485 -0700 @@ -645,11 +645,12 @@ #ifdef FEAT_VIMINFO /* - * Read in registers, history etc, but not marks, from the viminfo file + * Read in registers, history etc, but not marks, from the viminfo file. + * This is where v:oldfiles gets filled. */ if (*p_viminfo != NUL) { - read_viminfo(NULL, TRUE, FALSE, FALSE); + read_viminfo(NULL, VIF_WANT_INFO | VIF_GET_OLDFILES); TIME_MSG("reading viminfo"); } #endif @@ -1457,7 +1458,8 @@ ++initstr; } - if (TOLOWER_ASC(initstr[0]) == 'g' || initstr[0] == 'k') + /* "gvim" starts the GUI. Also accept "Gvim" for MS-Windows. */ + if (TOLOWER_ASC(initstr[0]) == 'g') { main_start_gui(); #ifdef FEAT_GUI @@ -1508,7 +1510,8 @@ early_arg_scan(parmp) mparm_T *parmp; { -#if defined(FEAT_XCLIPBOARD) || defined(FEAT_CLIENTSERVER) +#if defined(FEAT_XCLIPBOARD) || defined(FEAT_CLIENTSERVER) \ + || !defined(FEAT_NETBEANS_INTG) int argc = parmp->argc; char **argv = parmp->argv; int i; @@ -1580,6 +1583,14 @@ else if (STRICMP(argv[i], "--echo-wid") == 0) echo_wid_arg = TRUE; # endif +# ifndef FEAT_NETBEANS_INTG + else if (strncmp(argv[i], "-nb", (size_t)3) == 0) + { + mch_errmsg(_("'-nb' cannot be used: not enabled at compile time\n")); + mch_exit(2); + } +# endif + } #endif } @@ -2361,7 +2372,7 @@ * Is there any other system that cannot do this? */ close(0); - dup(2); + ignored = dup(2); #endif } diff -Naur vim72.orig/src/mark.c vim72/src/mark.c --- vim72.orig/src/mark.c 2008-08-08 15:06:49.000000000 -0700 +++ vim72/src/mark.c 2009-03-22 21:28:12.902752340 -0700 @@ -1627,15 +1627,17 @@ /* * Handle marks in the viminfo file: - * fp_out == NULL read marks for current buffer only - * fp_out != NULL copy marks for buffers not in buffer list + * fp_out != NULL: copy marks for buffers not in buffer list + * fp_out == NULL && (flags & VIF_WANT_MARKS): read marks for curbuf only + * fp_out == NULL && (flags & VIF_GET_OLDFILES | VIF_FORCEIT): fill v:oldfiles */ void -copy_viminfo_marks(virp, fp_out, count, eof) +copy_viminfo_marks(virp, fp_out, count, eof, flags) vir_T *virp; FILE *fp_out; int count; int eof; + int flags; { char_u *line = virp->vir_line; buf_T *buf; @@ -1647,10 +1649,23 @@ char_u *p; char_u *name_buf; pos_T pos; +#ifdef FEAT_EVAL + list_T *list = NULL; +#endif if ((name_buf = alloc(LSIZE)) == NULL) return; *name_buf = NUL; + +#ifdef FEAT_EVAL + if (fp_out == NULL && (flags & (VIF_GET_OLDFILES | VIF_FORCEIT))) + { + list = list_alloc(); + if (list != NULL) + set_vim_var_list(VV_OLDFILES, list); + } +#endif + num_marked_files = get_viminfo_parameter('\''); while (!eof && (count < num_marked_files || fp_out == NULL)) { @@ -1681,6 +1696,11 @@ p++; *p = NUL; +#ifdef FEAT_EVAL + if (list != NULL) + list_append_string(list, str, -1); +#endif + /* * If fp_out == NULL, load marks for current buffer. * If fp_out != NULL, copy marks for buffers not in buflist. @@ -1688,7 +1708,7 @@ load_marks = copy_marks_out = FALSE; if (fp_out == NULL) { - if (curbuf->b_ffname != NULL) + if ((flags & VIF_WANT_MARKS) && curbuf->b_ffname != NULL) { if (*name_buf == NUL) /* only need to do this once */ home_replace(NULL, curbuf->b_ffname, name_buf, LSIZE, TRUE); diff -Naur vim72.orig/src/mbyte.c vim72/src/mbyte.c --- vim72.orig/src/mbyte.c 2008-07-14 05:38:05.000000000 -0700 +++ vim72/src/mbyte.c 2009-03-22 21:29:14.046670485 -0700 @@ -717,7 +717,7 @@ * where mblen() returns 0 for invalid character. * Therefore, following condition includes 0. */ - (void)mblen(NULL, 0); /* First reset the state. */ + ignored = mblen(NULL, 0); /* First reset the state. */ if (mblen(buf, (size_t)1) <= 0) n = 2; else @@ -2540,7 +2540,6 @@ return (int)(p - q); } -#if defined(FEAT_EVAL) || defined(PROTO) /* * Copy a character from "*fp" to "*tp" and advance the pointers. */ @@ -2555,7 +2554,6 @@ *tp += l; *fp += l; } -#endif /* * Return the offset from "p" to the first byte of a character. When "p" is @@ -3133,7 +3131,7 @@ else s = p + 1; } - for (i = 0; s[i] != NUL && s + i < buf + sizeof(buf) - 1; ++i) + for (i = 0; s[i] != NUL && i < sizeof(buf) - 1; ++i) { if (s[i] == '_' || s[i] == '-') buf[i] = '-'; @@ -5280,7 +5278,7 @@ /*ARGSUSED*/ static void -preedit_start_cbproc(XIC xic, XPointer client_data, XPointer call_data) +preedit_start_cbproc(XIC thexic, XPointer client_data, XPointer call_data) { #ifdef XIM_DEBUG xim_log("xim_decide_input_style()\n"); @@ -5314,7 +5312,7 @@ /*ARGSUSED*/ static void -preedit_draw_cbproc(XIC xic, XPointer client_data, XPointer call_data) +preedit_draw_cbproc(XIC thexic, XPointer client_data, XPointer call_data) { XIMPreeditDrawCallbackStruct *draw_data; XIMText *text; @@ -5386,7 +5384,7 @@ draw_feedback = (char *)alloc(draw_data->chg_first + text->length); else - draw_feedback = realloc(draw_feedback, + draw_feedback = vim_realloc(draw_feedback, draw_data->chg_first + text->length); if (draw_feedback != NULL) { @@ -5455,7 +5453,7 @@ /*ARGSUSED*/ static void -preedit_caret_cbproc(XIC xic, XPointer client_data, XPointer call_data) +preedit_caret_cbproc(XIC thexic, XPointer client_data, XPointer call_data) { #ifdef XIM_DEBUG xim_log("preedit_caret_cbproc()\n"); @@ -5464,7 +5462,7 @@ /*ARGSUSED*/ static void -preedit_done_cbproc(XIC xic, XPointer client_data, XPointer call_data) +preedit_done_cbproc(XIC thexic, XPointer client_data, XPointer call_data) { #ifdef XIM_DEBUG xim_log("preedit_done_cbproc()\n"); diff -Naur vim72.orig/src/menu.c vim72/src/menu.c --- vim72.orig/src/menu.c 2008-06-21 12:53:43.000000000 -0700 +++ vim72/src/menu.c 2009-03-22 21:27:00.030081016 -0700 @@ -1120,6 +1120,7 @@ parent = menu; menu = menu->children; } + vim_free(path_name); /* Now we have found the matching menu, and we list the mappings */ /* Highlight title */ diff -Naur vim72.orig/src/message.c vim72/src/message.c --- vim72.orig/src/message.c 2008-07-09 11:24:55.000000000 -0700 +++ vim72/src/message.c 2009-03-22 21:32:11.106013969 -0700 @@ -976,7 +976,7 @@ } } else if (msg_scrolled > Rows - 2 - && (c == 'j' || c == K_DOWN || c == 'd')) + && (c == 'j' || c == K_DOWN || c == 'd' || c == 'f')) c = K_IGNORE; } } while ((had_got_int && c == Ctrl_C) @@ -2504,7 +2504,6 @@ break; case 'u': /* Up half a page */ - case K_PAGEUP: scroll = -(Rows / 2); break; @@ -2513,10 +2512,12 @@ break; case 'b': /* one page back */ + case K_PAGEUP: scroll = -(Rows - 1); break; case ' ': /* one extra page */ + case 'f': case K_PAGEDOWN: case K_LEFTMOUSE: scroll = Rows - 1; @@ -2552,7 +2553,6 @@ { /* Jump to the choices of the dialog. */ retval = TRUE; - lines_left = Rows - 1; } else #endif @@ -2560,6 +2560,9 @@ got_int = TRUE; quit_more = TRUE; } + /* When there is some more output (wrapping line) display that + * without another prompt. */ + lines_left = Rows - 1; break; #ifdef FEAT_CLIPBOARD @@ -3309,7 +3312,10 @@ { c = gui_mch_dialog(type, title, message, buttons, dfltbutton, textfield); - msg_end_prompt(); + /* avoid a hit-enter prompt without clearing the cmdline */ + need_wait_return = FALSE; + emsg_on_display = FALSE; + cmdline_row = msg_row; /* Flush output to avoid that further messages and redrawing is done * in the wrong order. */ @@ -4556,7 +4562,13 @@ remove_trailing_zeroes = TRUE; } - if (fmt_spec == 'f' && abs_f > 1.0e307) + if (fmt_spec == 'f' && +#ifdef VAX + abs_f > 1.0e38 +#else + abs_f > 1.0e307 +#endif + ) { /* Avoid a buffer overflow */ strcpy(tmp, "inf"); @@ -4585,61 +4597,62 @@ if (remove_trailing_zeroes) { int i; - char *p; + char *tp; /* Using %g or %G: remove superfluous zeroes. */ if (fmt_spec == 'f') - p = tmp + str_arg_l - 1; + tp = tmp + str_arg_l - 1; else { - p = (char *)vim_strchr((char_u *)tmp, + tp = (char *)vim_strchr((char_u *)tmp, fmt_spec == 'e' ? 'e' : 'E'); - if (p != NULL) + if (tp != NULL) { /* Remove superfluous '+' and leading * zeroes from the exponent. */ - if (p[1] == '+') + if (tp[1] == '+') { /* Change "1.0e+07" to "1.0e07" */ - STRMOVE(p + 1, p + 2); + STRMOVE(tp + 1, tp + 2); --str_arg_l; } - i = (p[1] == '-') ? 2 : 1; - while (p[i] == '0') + i = (tp[1] == '-') ? 2 : 1; + while (tp[i] == '0') { /* Change "1.0e07" to "1.0e7" */ - STRMOVE(p + i, p + i + 1); + STRMOVE(tp + i, tp + i + 1); --str_arg_l; } - --p; + --tp; } } - if (p != NULL && !precision_specified) + if (tp != NULL && !precision_specified) /* Remove trailing zeroes, but keep the one * just after a dot. */ - while (p > tmp + 2 && *p == '0' && p[-1] != '.') + while (tp > tmp + 2 && *tp == '0' + && tp[-1] != '.') { - STRMOVE(p, p + 1); - --p; + STRMOVE(tp, tp + 1); + --tp; --str_arg_l; } } else { - char *p; + char *tp; /* Be consistent: some printf("%e") use 1.0e+12 * and some 1.0e+012. Remove one zero in the last * case. */ - p = (char *)vim_strchr((char_u *)tmp, + tp = (char *)vim_strchr((char_u *)tmp, fmt_spec == 'e' ? 'e' : 'E'); - if (p != NULL && (p[1] == '+' || p[1] == '-') - && p[2] == '0' - && vim_isdigit(p[3]) - && vim_isdigit(p[4])) + if (tp != NULL && (tp[1] == '+' || tp[1] == '-') + && tp[2] == '0' + && vim_isdigit(tp[3]) + && vim_isdigit(tp[4])) { - STRMOVE(p + 2, p + 3); + STRMOVE(tp + 2, tp + 3); --str_arg_l; } } diff -Naur vim72.orig/src/misc1.c vim72/src/misc1.c --- vim72.orig/src/misc1.c 2008-07-12 12:20:53.000000000 -0700 +++ vim72/src/misc1.c 2009-03-22 21:32:58.837074452 -0700 @@ -2955,6 +2955,8 @@ int col; /* column for message; non-zero when in insert mode and 'showmode' is on */ { + static char *w_readonly = N_("W10: Warning: Changing a readonly file"); + if (curbuf->b_did_warn == FALSE && curbufIsChanged() == 0 #ifdef FEAT_AUTOCMD @@ -2977,8 +2979,10 @@ if (msg_row == Rows - 1) msg_col = col; msg_source(hl_attr(HLF_W)); - MSG_PUTS_ATTR(_("W10: Warning: Changing a readonly file"), - hl_attr(HLF_W) | MSG_HIST); + MSG_PUTS_ATTR(_(w_readonly), hl_attr(HLF_W) | MSG_HIST); +#ifdef FEAT_EVAL + set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_readonly), -1); +#endif msg_clr_eos(); (void)msg_end(); if (msg_silent == 0 && !silent_mode) @@ -3245,9 +3249,9 @@ /* When using ":silent" assume that was entered. */ if (mouse_used != NULL) - MSG_PUTS(_("Type number or click with mouse ( cancels): ")); + MSG_PUTS(_("Type number and or click with mouse (empty cancels): ")); else - MSG_PUTS(_("Choice number ( cancels): ")); + MSG_PUTS(_("Type number and (empty cancels): ")); /* Set the state such that text can be selected/copied/pasted and we still * get mouse events. */ diff -Naur vim72.orig/src/misc2.c vim72/src/misc2.c --- vim72.orig/src/misc2.c 2008-07-23 12:12:56.000000000 -0700 +++ vim72/src/misc2.c 2009-03-22 21:32:41.367955022 -0700 @@ -496,7 +496,8 @@ { colnr_T len; #ifdef FEAT_VIRTUALEDIT - colnr_T oldcol = curwin->w_cursor.col + curwin->w_cursor.coladd; + colnr_T oldcol = curwin->w_cursor.col; + colnr_T oldcoladd = curwin->w_cursor.col + curwin->w_cursor.coladd; #endif len = (colnr_T)STRLEN(ml_get_curline()); @@ -535,7 +536,13 @@ if (oldcol == MAXCOL) curwin->w_cursor.coladd = 0; else if (ve_flags == VE_ALL) - curwin->w_cursor.coladd = oldcol - curwin->w_cursor.col; + { + if (oldcoladd > curwin->w_cursor.col) + curwin->w_cursor.coladd = oldcoladd - curwin->w_cursor.col; + else + /* avoid weird number when there is a miscalculation or overflow */ + curwin->w_cursor.coladd = 0; + } #endif } @@ -873,7 +880,7 @@ /* 3. check for available memory: call mch_avail_mem() */ if (mch_avail_mem(TRUE) < KEEP_ROOM && !releasing) { - vim_free((char *)p); /* System is low... no go! */ + free((char *)p); /* System is low... no go! */ p = NULL; } else @@ -1010,6 +1017,9 @@ # if defined(FEAT_PROFILE) do_cmdline_cmd((char_u *)"profdel *"); # endif +# if defined(FEAT_KEYMAP) + do_cmdline_cmd((char_u *)"set keymap="); +#endif # ifdef FEAT_TITLE free_titles(); @@ -1034,6 +1044,9 @@ free_regexp_stuff(); free_tag_stuff(); free_cd_dir(); +# ifdef FEAT_SIGNS + free_signs(); +# endif # ifdef FEAT_EVAL set_expr_line(NULL); # endif @@ -1257,7 +1270,6 @@ return escaped_string; } -#if !defined(BACKSLASH_IN_FILENAME) || defined(FEAT_EVAL) || defined(PROTO) /* * Return TRUE when 'shell' has "csh" in the tail. */ @@ -1266,9 +1278,7 @@ { return (strstr((char *)gettail(p_sh), "csh") != NULL); } -#endif -#if defined(FEAT_EVAL) || defined(PROTO) /* * Escape "string" for use as a shell argument with system(). * This uses single quotes, except when we know we need to use double qoutes @@ -1391,7 +1401,6 @@ return escaped_string; } -#endif /* * Like vim_strsave(), but make all characters uppercase. @@ -2565,7 +2574,7 @@ int key; int dlen = 0; - key = find_special_key(srcp, &modifiers, keycode); + key = find_special_key(srcp, &modifiers, keycode, FALSE); if (key == 0) return 0; @@ -2601,10 +2610,11 @@ * returns 0 if there is no match. */ int -find_special_key(srcp, modp, keycode) +find_special_key(srcp, modp, keycode, keep_x_key) char_u **srcp; int *modp; - int keycode; /* prefer key code, e.g. K_DEL instead of DEL */ + int keycode; /* prefer key code, e.g. K_DEL instead of DEL */ + int keep_x_key; /* don't translate xHome to Home key */ { char_u *last_dash; char_u *end_of_name; @@ -2672,7 +2682,8 @@ else { key = get_special_key_code(last_dash + 1); - key = handle_x_keys(key); + if (!keep_x_key) + key = handle_x_keys(key); } /* @@ -4698,7 +4709,8 @@ stackp->ffs_filearray_cur = i + 1; ff_push(search_ctx, stackp); - simplify_filename(file_path); + if (!path_with_url(file_path)) + simplify_filename(file_path); if (mch_dirname(ff_expand_buffer, MAXPATHL) == OK) { diff -Naur vim72.orig/src/move.c vim72/src/move.c --- vim72.orig/src/move.c 2008-07-12 09:26:47.000000000 -0700 +++ vim72/src/move.c 2009-03-22 21:28:40.376510966 -0700 @@ -280,18 +280,20 @@ if (curwin->w_botline <= curbuf->b_ml.ml_line_count) { - if (curwin->w_cursor.lnum < curwin->w_botline - && ((long)curwin->w_cursor.lnum + if (curwin->w_cursor.lnum < curwin->w_botline) + { + if (((long)curwin->w_cursor.lnum >= (long)curwin->w_botline - p_so #ifdef FEAT_FOLDING || hasAnyFolding(curwin) #endif )) - { + { lineoff_T loff; - /* Cursor is above botline, check if there are 'scrolloff' - * window lines below the cursor. If not, need to scroll. */ + /* Cursor is (a few lines) above botline, check if there are + * 'scrolloff' window lines below the cursor. If not, need to + * scroll. */ n = curwin->w_empty_rows; loff.lnum = curwin->w_cursor.lnum; #ifdef FEAT_FOLDING @@ -317,6 +319,10 @@ if (n >= p_so) /* sufficient context, no need to scroll */ check_botline = FALSE; + } + else + /* sufficient context, no need to scroll */ + check_botline = FALSE; } if (check_botline) { @@ -509,6 +515,9 @@ /* Approximate the value of w_botline */ wp->w_botline += lnum - wp->w_topline; wp->w_topline = lnum; +#ifdef FEAT_AUTOCMD + wp->w_topline_was_set = TRUE; +#endif #ifdef FEAT_DIFF wp->w_topfill = 0; #endif diff -Naur vim72.orig/src/nbdebug.c vim72/src/nbdebug.c --- vim72.orig/src/nbdebug.c 2008-06-22 08:38:58.000000000 -0700 +++ vim72/src/nbdebug.c 2009-03-22 21:31:41.800136053 -0700 @@ -33,7 +33,6 @@ u_int nb_dlevel = 0; /* nb_debug verbosity level */ void nbdb(char *, ...); -void nbtrace(char *, ...); static int lookup(char *); #ifdef USE_NB_ERRORHANDLER @@ -100,25 +99,6 @@ } /* end nbdebug_log_init */ - - -void -nbtrace( - char *fmt, - ...) -{ - va_list ap; - - if (nb_debug!= NULL && (nb_dlevel & (NB_TRACE | NB_TRACE_VERBOSE))) { - va_start(ap, fmt); - vfprintf(nb_debug, fmt, ap); - va_end(ap); - fflush(nb_debug); - } - -} /* end nbtrace */ - - void nbdbg( char *fmt, @@ -136,23 +116,6 @@ } /* end nbdbg */ -void -nbprt( - char *fmt, - ...) -{ - va_list ap; - - if (nb_debug != NULL && nb_dlevel & NB_PRINT) { - va_start(ap, fmt); - vfprintf(nb_debug, fmt, ap); - va_end(ap); - fflush(nb_debug); - } - -} /* end nbprt */ - - static int lookup( char *file) diff -Naur vim72.orig/src/nbdebug.h vim72/src/nbdebug.h --- vim72.orig/src/nbdebug.h 2008-06-22 07:31:50.000000000 -0700 +++ vim72/src/nbdebug.h 2009-03-22 21:31:41.800136053 -0700 @@ -43,8 +43,6 @@ void nbdbg(char *, ...); -void nbprt(char *, ...); -void nbtrace(char *, ...); void nbdebug_wait __ARGS((u_int wait_flags, char *wait_var, u_int wait_secs)); void nbdebug_log_init __ARGS((char *log_var, char *level_var)); @@ -70,19 +68,5 @@ { } -void -nbprt( - char *fmt, - ...) -{ -} - -void -nbtrace( - char *fmt, - ...) -{ -} - #endif /* NBDEBUG */ #endif /* NBDEBUG_H */ diff -Naur vim72.orig/src/netbeans.c vim72/src/netbeans.c --- vim72.orig/src/netbeans.c 2008-07-13 09:19:54.000000000 -0700 +++ vim72/src/netbeans.c 2009-03-22 21:31:39.383983238 -0700 @@ -1043,7 +1043,7 @@ nbdebug(("EVT: %s", buf)); /* nb_send(buf, "netbeans_end"); avoid "write failed" messages */ if (sd >= 0) - sock_write(sd, buf, (int)STRLEN(buf)); /* ignore errors */ + ignored = sock_write(sd, buf, (int)STRLEN(buf)); } } @@ -1921,7 +1921,7 @@ vim_free(path); if (bufp == NULL) { - nbdebug((" File %s not found in setBufferNumber\n", args)); + nbdebug((" File %s not found in setBufferNumber\n", args)); EMSG2("E642: File %s not found in setBufferNumber", args); return FAIL; } @@ -2277,9 +2277,6 @@ int serNum; int localTypeNum; int typeNum; -# ifdef NBDEBUG - int len; -# endif pos_T *pos; if (buf == NULL || buf->bufp == NULL) @@ -2303,13 +2300,10 @@ pos = get_off_or_lnum(buf->bufp, &args); cp = (char *)args; -# ifdef NBDEBUG - len = -# endif - strtol(cp, &cp, 10); + ignored = (int)strtol(cp, &cp, 10); args = (char_u *)cp; # ifdef NBDEBUG - if (len != -1) + if (ignored != -1) { nbdebug((" partial line annotation -- Not Yet Implemented!\n")); } @@ -2321,7 +2315,7 @@ } if (pos) { - coloncmd(":sign place %d line=%d name=%d buffer=%d", + coloncmd(":sign place %d line=%ld name=%d buffer=%d", serNum, pos->lnum, typeNum, buf->bufp->b_fnum); if (typeNum == curPCtype) coloncmd(":sign jump %d buffer=%d", serNum, @@ -2425,7 +2419,7 @@ GUARDED) == 0) { coloncmd( - ":sign place %d line=%d name=%d buffer=%d", + ":sign place %d line=%ld name=%d buffer=%d", guardId++, lnum, GUARDED, buf->bufp->b_fnum); } @@ -2924,44 +2918,26 @@ } /* - * Tell netbeans a file was closed. + * Tell netbeans that a file was deleted or wiped out. */ void -netbeans_file_closed(buf_T *bufp) +netbeans_file_killed(buf_T *bufp) { int bufno = nb_getbufno(bufp); nbbuf_T *nbbuf = nb_get_buf(bufno); char buffer[2*MAXPATHL]; - if (!haveConnection || bufno < 0) - return; - - if (!netbeansCloseFile) - { - nbdebug(("Ignoring file_closed for %s. File was closed from IDE\n", - bufp->b_ffname)); + if (!haveConnection || bufno == -1) return; - } - - nbdebug(("netbeans_file_closed:\n")); - nbdebug((" Closing bufno: %d", bufno)); - if (curbuf != NULL && curbuf != bufp) - { - nbdebug((" Curbuf bufno: %d\n", nb_getbufno(curbuf))); - } - else if (curbuf == bufp) - { - nbdebug((" curbuf == bufp\n")); - } - if (bufno <= 0) - return; + nbdebug(("netbeans_file_killed:\n")); + nbdebug((" Killing bufno: %d", bufno)); sprintf(buffer, "%d:killed=%d\n", bufno, r_cmdno); nbdebug(("EVT: %s", buffer)); - nb_send(buffer, "netbeans_file_closed"); + nb_send(buffer, "netbeans_file_killed"); if (nbbuf != NULL) nbbuf->bufp = NULL; diff -Naur vim72.orig/src/normal.c vim72/src/normal.c --- vim72.orig/src/normal.c 2008-07-31 13:03:08.000000000 -0700 +++ vim72/src/normal.c 2009-03-22 21:31:27.235204917 -0700 @@ -183,6 +183,8 @@ static void nv_cursorhold __ARGS((cmdarg_T *cap)); #endif +static char *e_noident = N_("E349: No identifier under cursor"); + /* * Function to be called for a Normal or Visual mode command. * The argument is a cmdarg_T. @@ -578,6 +580,9 @@ static int old_mapped_len = 0; #endif int idx; +#ifdef FEAT_EVAL + int set_prevcount = FALSE; +#endif vim_memset(&ca, 0, sizeof(ca)); /* also resets ca.retval */ ca.oap = oap; @@ -613,7 +618,12 @@ /* When not finishing an operator and no register name typed, reset the * count. */ if (!finish_op && !oap->regname) + { ca.opcount = 0; +#ifdef FEAT_EVAL + set_prevcount = TRUE; +#endif + } #ifdef FEAT_AUTOCMD /* Restore counts from before receiving K_CURSORHOLD. This means after @@ -641,10 +651,7 @@ * Get the command character from the user. */ c = safe_vgetc(); - -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(c, TRUE); -#endif #ifdef FEAT_VISUAL /* @@ -717,7 +724,15 @@ * command, so that v:count can be used in an expression mapping * right after the count. */ if (toplevel && stuff_empty()) - set_vcount(ca.count0, ca.count0 == 0 ? 1 : ca.count0); + { + long count = ca.count0; + + /* multiply with ca.opcount the same way as below */ + if (ca.opcount != 0) + count = ca.opcount * (count == 0 ? 1 : count); + set_vcount(count, count == 0 ? 1 : count, set_prevcount); + set_prevcount = FALSE; /* only set v:prevcount once */ + } #endif if (ctrl_w) { @@ -726,9 +741,7 @@ } ++no_zero_mapping; /* don't map zero here */ c = plain_vgetc(); -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(c, TRUE); -#endif --no_zero_mapping; if (ctrl_w) { @@ -751,9 +764,7 @@ ++no_mapping; ++allow_keys; /* no mapping for nchar, but keys */ c = plain_vgetc(); /* get next character */ -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(c, TRUE); -#endif --no_mapping; --allow_keys; #ifdef FEAT_CMDL_INFO @@ -804,7 +815,7 @@ * Only set v:count when called from main() and not a stuffed command. */ if (toplevel && stuff_empty()) - set_vcount(ca.count0, ca.count1); + set_vcount(ca.count0, ca.count1, set_prevcount); #endif /* @@ -941,9 +952,7 @@ * "gr", "g'" and "g`". */ ca.nchar = plain_vgetc(); -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(ca.nchar, TRUE); -#endif #ifdef FEAT_CMDL_INFO need_flushbuf |= add_to_showcmd(ca.nchar); #endif @@ -1044,10 +1053,8 @@ } #endif -#ifdef FEAT_LANGMAP /* adjust chars > 127, except after "tTfFr" commands */ LANGMAP_ADJUST(*cp, !lang); -#endif #ifdef FEAT_RIGHTLEFT /* adjust Hebrew mapped char */ if (p_hkmap && lang && KeyTyped) @@ -1132,7 +1139,8 @@ out_flush(); #endif #ifdef FEAT_AUTOCMD - did_cursorhold = FALSE; + if (ca.cmdchar != K_IGNORE) + did_cursorhold = FALSE; #endif State = NORMAL; @@ -3509,7 +3517,7 @@ if (find_type & FIND_STRING) EMSG(_("E348: No string under cursor")); else - EMSG(_("E349: No identifier under cursor")); + EMSG(_(e_noident)); return 0; } ptr += col; @@ -4611,9 +4619,7 @@ ++no_mapping; ++allow_keys; /* no mapping for nchar, but allow key codes */ nchar = plain_vgetc(); -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(nchar, TRUE); -#endif --no_mapping; --allow_keys; #ifdef FEAT_CMDL_INFO @@ -4969,9 +4975,7 @@ ++no_mapping; ++allow_keys; /* no mapping for nchar, but allow key codes */ nchar = plain_vgetc(); -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(nchar, TRUE); -#endif --no_mapping; --allow_keys; #ifdef FEAT_CMDL_INFO @@ -5469,6 +5473,20 @@ STRCPY(buf, "he! "); else { + /* An external command will probably use an argument starting + * with "-" as an option. To avoid trouble we skip the "-". */ + while (*ptr == '-' && n > 0) + { + ++ptr; + --n; + } + if (n == 0) + { + EMSG(_(e_noident)); /* found dashes only */ + vim_free(buf); + return; + } + /* When a count is given, turn it into a range. Is this * really what we want? */ isman = (STRCMP(kp, "man") == 0); @@ -5511,37 +5529,59 @@ /* * Now grab the chars in the identifier */ - if (cmdchar == '*') - aux_ptr = (char_u *)(p_magic ? "/.*~[^$\\" : "/^$\\"); - else if (cmdchar == '#') - aux_ptr = (char_u *)(p_magic ? "/?.*~[^$\\" : "/?^$\\"); - else if (cmdchar == 'K' && !kp_help) - aux_ptr = (char_u *)" \t\\\"|!"; - else - /* Don't escape spaces and Tabs in a tag with a backslash */ - aux_ptr = (char_u *)"\\|\""; - - p = buf + STRLEN(buf); - while (n-- > 0) - { - /* put a backslash before \ and some others */ - if (vim_strchr(aux_ptr, *ptr) != NULL) - *p++ = '\\'; -#ifdef FEAT_MBYTE - /* When current byte is a part of multibyte character, copy all bytes - * of that character. */ - if (has_mbyte) + if (cmdchar == 'K' && !kp_help) + { + /* Escape the argument properly for a shell command */ + ptr = vim_strnsave(ptr, n); + p = vim_strsave_shellescape(ptr, TRUE); + vim_free(ptr); + if (p == NULL) { - int i; - int len = (*mb_ptr2len)(ptr) - 1; - - for (i = 0; i < len && n >= 1; ++i, --n) - *p++ = *ptr++; + vim_free(buf); + return; + } + buf = (char_u *)vim_realloc(buf, STRLEN(buf) + STRLEN(p) + 1); + if (buf == NULL) + { + vim_free(buf); + vim_free(p); + return; } + STRCAT(buf, p); + vim_free(p); + } + else + { + if (cmdchar == '*') + aux_ptr = (char_u *)(p_magic ? "/.*~[^$\\" : "/^$\\"); + else if (cmdchar == '#') + aux_ptr = (char_u *)(p_magic ? "/?.*~[^$\\" : "/?^$\\"); + else + /* Don't escape spaces and Tabs in a tag with a backslash */ + aux_ptr = (char_u *)"\\|\"\n*?["; + + p = buf + STRLEN(buf); + while (n-- > 0) + { + /* put a backslash before \ and some others */ + if (vim_strchr(aux_ptr, *ptr) != NULL) + *p++ = '\\'; +#ifdef FEAT_MBYTE + /* When current byte is a part of multibyte character, copy all + * bytes of that character. */ + if (has_mbyte) + { + int i; + int len = (*mb_ptr2len)(ptr) - 1; + + for (i = 0; i < len && n >= 1; ++i, --n) + *p++ = *ptr++; + } #endif - *p++ = *ptr++; + *p++ = *ptr++; + } + *p = NUL; } - *p = NUL; /* * Execute the command. @@ -6728,6 +6768,8 @@ /* Visual mode "r" */ if (VIsual_active) { + if (got_int) + reset_VIsual(); nv_operator(cap); return; } @@ -7784,7 +7826,7 @@ else i = curwin->w_leftcol; /* Go to the middle of the screen line. When 'number' is on and lines - * are wrapping the middle can be more to the left.*/ + * are wrapping the middle can be more to the left. */ if (cap->nchar == 'm') i += (W_WIDTH(curwin) - curwin_col_off() + ((curwin->w_p_wrap && i > 0) diff -Naur vim72.orig/src/ops.c vim72/src/ops.c --- vim72.orig/src/ops.c 2008-06-21 13:08:59.000000000 -0700 +++ vim72/src/ops.c 2009-03-22 21:32:36.451638218 -0700 @@ -72,11 +72,11 @@ */ struct block_def { - int startspaces; /* 'extra' cols of first char */ - int endspaces; /* 'extra' cols of first char */ + int startspaces; /* 'extra' cols before first char */ + int endspaces; /* 'extra' cols after last char */ int textlen; /* chars in block */ - char_u *textstart; /* pointer to 1st char in block */ - colnr_T textcol; /* cols of chars (at least part.) in block */ + char_u *textstart; /* pointer to 1st char (partially) in block */ + colnr_T textcol; /* index of chars (partially) in block */ colnr_T start_vcol; /* start col of 1st char wholly inside block */ colnr_T end_vcol; /* start col of 1st char wholly after block */ #ifdef FEAT_VISUALEXTRA @@ -382,15 +382,14 @@ { int left = (oap->op_type == OP_LSHIFT); int oldstate = State; - int total, split; - char_u *newp, *oldp, *midp, *ptr; + int total; + char_u *newp, *oldp; int oldcol = curwin->w_cursor.col; int p_sw = (int)curbuf->b_p_sw; int p_ts = (int)curbuf->b_p_ts; struct block_def bd; - int internal = 0; int incr; - colnr_T vcol, col = 0, ws_vcol; + colnr_T ws_vcol; int i = 0, j = 0; int len; @@ -456,67 +455,89 @@ } else /* left */ { - vcol = oap->start_vcol; - /* walk vcol past ws to be removed */ - for (midp = oldp + bd.textcol; - vcol < (oap->start_vcol + total) && vim_iswhite(*midp); ) - { - incr = lbr_chartabsize_adv(&midp, (colnr_T)vcol); - vcol += incr; - } - /* internal is the block-internal ws replacing a split TAB */ - if (vcol > (oap->start_vcol + total)) - { - /* we have to split the TAB *(midp-1) */ - internal = vcol - (oap->start_vcol + total); - } - /* if 'expandtab' is not set, use TABs */ + colnr_T destination_col; /* column to which text in block will + be shifted */ + char_u *verbatim_copy_end; /* end of the part of the line which is + copied verbatim */ + colnr_T verbatim_copy_width;/* the (displayed) width of this part + of line */ + unsigned fill; /* nr of spaces that replace a TAB */ + unsigned new_line_len; /* the length of the line after the + block shift */ + size_t block_space_width; + size_t shift_amount; + char_u *non_white = bd.textstart; + colnr_T non_white_col; - split = bd.startspaces + internal; - if (split > 0) - { - if (!curbuf->b_p_et) - { - for (ptr = oldp, col = 0; ptr < oldp+bd.textcol; ) - col += lbr_chartabsize_adv(&ptr, (colnr_T)col); + /* + * Firstly, let's find the first non-whitespace character that is + * displayed after the block's start column and the character's column + * number. Also, let's calculate the width of all the whitespace + * characters that are displayed in the block and precede the searched + * non-whitespace character. + */ - /* col+1 now equals the start col of the first char of the - * block (may be < oap.start_vcol if we're splitting a TAB) */ - i = ((col % p_ts) + split) / p_ts; /* number of tabs */ - } - if (i) - j = ((col % p_ts) + split) % p_ts; /* number of spp */ - else - j = split; - } + /* If "bd.startspaces" is set, "bd.textstart" points to the character, + * the part of which is displayed at the block's beginning. Let's start + * searching from the next character. */ + if (bd.startspaces) + mb_ptr_adv(non_white); - newp = alloc_check(bd.textcol + i + j + (unsigned)STRLEN(midp) + 1); - if (newp == NULL) - return; - vim_memset(newp, NUL, (size_t)(bd.textcol + i + j + STRLEN(midp) + 1)); + /* The character's column is in "bd.start_vcol". */ + non_white_col = bd.start_vcol; - /* copy first part we want to keep */ - mch_memmove(newp, oldp, (size_t)bd.textcol); - /* Now copy any TABS and spp to ensure correct alignment! */ - while (vim_iswhite(*midp)) + while (vim_iswhite(*non_white)) { - if (*midp == TAB) - i++; - else /*space */ - j++; - midp++; + incr = lbr_chartabsize_adv(&non_white, non_white_col); + non_white_col += incr; } - /* We might have an extra TAB worth of spp now! */ - if (j / p_ts && !curbuf->b_p_et) + + block_space_width = non_white_col - oap->start_vcol; + /* We will shift by "total" or "block_space_width", whichever is less. + */ + shift_amount = (block_space_width < total? block_space_width: total); + + /* The column to which we will shift the text. */ + destination_col = non_white_col - shift_amount; + + /* Now let's find out how much of the beginning of the line we can + * reuse without modification. */ + verbatim_copy_end = bd.textstart; + verbatim_copy_width = bd.start_vcol; + + /* If "bd.startspaces" is set, "bd.textstart" points to the character + * preceding the block. We have to subtract its width to obtain its + * column number. */ + if (bd.startspaces) + verbatim_copy_width -= bd.start_char_vcols; + while (verbatim_copy_width < destination_col) { - i++; - j -= p_ts; + incr = lbr_chartabsize(verbatim_copy_end, verbatim_copy_width); + if (verbatim_copy_width + incr > destination_col) + break; + verbatim_copy_width += incr; + mb_ptr_adv(verbatim_copy_end); } - copy_chars(newp + bd.textcol, (size_t)i, TAB); - copy_spaces(newp + bd.textcol + i, (size_t)j); - /* the end */ - STRMOVE(newp + STRLEN(newp), midp); + /* If "destination_col" is different from the width of the initial + * part of the line that will be copied, it means we encountered a tab + * character, which we will have to partly replace with spaces. */ + fill = destination_col - verbatim_copy_width; + + /* The replacement line will consist of: + * - the beginning of the original line up to "verbatim_copy_end", + * - "fill" number of spaces, + * - the rest of the line, pointed to by non_white. */ + new_line_len = (unsigned)(verbatim_copy_end - oldp) + + fill + + (unsigned)STRLEN(non_white) + 1; + + newp = alloc_check(new_line_len); + if (newp == NULL) + return; + mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp)); + copy_spaces(newp + (verbatim_copy_end - oldp), (size_t)fill); + STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white); } /* replace the line */ ml_replace(curwin->w_cursor.lnum, newp, FALSE); @@ -2209,12 +2230,15 @@ { for (; pos.lnum <= oap->end.lnum; ++pos.lnum) { + int one_change; + block_prep(oap, &bd, pos.lnum, FALSE); pos.col = bd.textcol; - did_change = swapchars(oap->op_type, &pos, bd.textlen); + one_change = swapchars(oap->op_type, &pos, bd.textlen); + did_change |= one_change; # ifdef FEAT_NETBEANS_INTG - if (usingNetbeans && did_change) + if (usingNetbeans && one_change) { char_u *ptr = ml_get_buf(curbuf, pos.lnum, FALSE); @@ -4848,7 +4872,8 @@ * - textlen includes the first/last char to be (partly) deleted * - start/endspaces is the number of columns that are taken by the * first/last deleted char minus the number of columns that have to be - * deleted. for yank and tilde: + * deleted. + * for yank and tilde: * - textlen includes the first/last char to be wholly yanked * - start/endspaces is the number of columns of the first/last yanked char * that are to be yanked. diff -Naur vim72.orig/src/option.c vim72/src/option.c --- vim72.orig/src/option.c 2008-07-18 06:05:33.000000000 -0700 +++ vim72/src/option.c 2009-03-22 21:32:58.841075011 -0700 @@ -2593,13 +2593,13 @@ #ifdef FEAT_VIMINFO (char_u *)&p_viminfo, PV_NONE, #if defined(MSDOS) || defined(MSWIN) || defined(OS2) - {(char_u *)"", (char_u *)"'20,<50,s10,h,rA:,rB:"} + {(char_u *)"", (char_u *)"'100,<50,s10,h,rA:,rB:"} #else # ifdef AMIGA {(char_u *)"", - (char_u *)"'20,<50,s10,h,rdf0:,rdf1:,rdf2:"} + (char_u *)"'100,<50,s10,h,rdf0:,rdf1:,rdf2:"} # else - {(char_u *)"", (char_u *)"'20,<50,s10,h"} + {(char_u *)"", (char_u *)"'100,<50,s10,h"} # endif #endif #else @@ -4119,11 +4119,23 @@ && options[opt_idx].var == VAR_WIN) goto skip; - /* Disallow changing some options from modelines */ - if ((opt_flags & OPT_MODELINE) && (flags & P_SECURE)) + /* Disallow changing some options from modelines. */ + if (opt_flags & OPT_MODELINE) { - errmsg = (char_u *)_("E520: Not allowed in a modeline"); - goto skip; + if (flags & P_SECURE) + { + errmsg = (char_u *)_("E520: Not allowed in a modeline"); + goto skip; + } +#ifdef FEAT_DIFF + /* In diff mode some options are overruled. This avoids that + * 'foldmethod' becomes "marker" instead of "diff" and that + * "wrap" gets set. */ + if (curwin->w_p_diff + && (options[opt_idx].indir == PV_FDM + || options[opt_idx].indir == PV_WRAP)) + goto skip; +#endif } #ifdef HAVE_SANDBOX @@ -5268,6 +5280,21 @@ } #endif +#ifdef FEAT_TITLE +static void redraw_titles __ARGS((void)); + +/* + * Redraw the window title and/or tab page text later. + */ +static void redraw_titles() +{ + need_maketitle = TRUE; +# ifdef FEAT_WINDOWS + redraw_tabline = TRUE; +# endif +} +#endif + /* * Set a string option to a new value (without checking the effect). * The string is copied into allocated memory. @@ -5407,6 +5434,10 @@ int did_chartab = FALSE; char_u **gvarp; long_u free_oldval = (options[opt_idx].flags & P_ALLOCED); +#ifdef FEAT_GUI + /* set when changing an option that only requires a redraw in the GUI */ + int redraw_gui_only = FALSE; +#endif /* Get the global option to compare with, otherwise we would have to check * two values for all local options. */ @@ -5668,7 +5699,7 @@ { # ifdef FEAT_TITLE /* May show a "+" in the title now. */ - need_maketitle = TRUE; + redraw_titles(); # endif /* Add 'fileencoding' to the swap file. */ ml_setflags(curbuf); @@ -5687,7 +5718,7 @@ { errmsg = mb_init(); # ifdef FEAT_TITLE - need_maketitle = TRUE; + redraw_titles(); # endif } } @@ -5766,14 +5797,28 @@ /* load or unload key mapping tables */ errmsg = keymap_init(); - /* When successfully installed a new keymap switch on using it. */ - if (*curbuf->b_p_keymap != NUL && errmsg == NULL) + if (errmsg == NULL) { - curbuf->b_p_iminsert = B_IMODE_LMAP; - if (curbuf->b_p_imsearch != B_IMODE_USE_INSERT) - curbuf->b_p_imsearch = B_IMODE_LMAP; - set_iminsert_global(); - set_imsearch_global(); + if (*curbuf->b_p_keymap != NUL) + { + /* Installed a new keymap, switch on using it. */ + curbuf->b_p_iminsert = B_IMODE_LMAP; + if (curbuf->b_p_imsearch != B_IMODE_USE_INSERT) + curbuf->b_p_imsearch = B_IMODE_LMAP; + } + else + { + /* Cleared the keymap, may reset 'iminsert' and 'imsearch'. */ + if (curbuf->b_p_iminsert == B_IMODE_LMAP) + curbuf->b_p_iminsert = B_IMODE_NONE; + if (curbuf->b_p_imsearch == B_IMODE_LMAP) + curbuf->b_p_imsearch = B_IMODE_USE_INSERT; + } + if ((opt_flags & OPT_LOCAL) == 0) + { + set_iminsert_global(); + set_imsearch_global(); + } # ifdef FEAT_WINDOWS status_redraw_curbuf(); # endif @@ -5796,7 +5841,7 @@ else curbuf->b_p_tx = FALSE; #ifdef FEAT_TITLE - need_maketitle = TRUE; + redraw_titles(); #endif /* update flag in swap file */ ml_setflags(curbuf); @@ -5977,15 +6022,23 @@ /* ":set t_Co=0" and ":set t_Co=1" do ":set t_Co=" */ if (varp == &T_CCO) { - t_colors = atoi((char *)T_CCO); - if (t_colors <= 1) + int colors = atoi((char *)T_CCO); + + /* Only reinitialize colors if t_Co value has really changed to + * avoid expensive reload of colorscheme if t_Co is set to the + * same value multiple times. */ + if (colors != t_colors) { - if (new_value_alloced) - vim_free(T_CCO); - T_CCO = empty_option; + t_colors = colors; + if (t_colors <= 1) + { + if (new_value_alloced) + vim_free(T_CCO); + T_CCO = empty_option; + } + /* We now have a different color setup, initialize it again. */ + init_highlight(TRUE, FALSE); } - /* We now have a different color setup, initialize it again. */ - init_highlight(TRUE, FALSE); } ttest(FALSE); if (varp == &T_ME) @@ -6055,6 +6108,7 @@ errmsg = (char_u *)N_("E596: Invalid font(s)"); } } + redraw_gui_only = TRUE; } # ifdef FEAT_XFONTSET else if (varp == &p_guifontset) @@ -6063,6 +6117,7 @@ errmsg = (char_u *)N_("E597: can't select fontset"); else if (gui.in_use && gui_init_font(p_guifontset, TRUE) != OK) errmsg = (char_u *)N_("E598: Invalid fontset"); + redraw_gui_only = TRUE; } # endif # ifdef FEAT_MBYTE @@ -6072,6 +6127,7 @@ errmsg = (char_u *)N_("E533: can't select wide font"); else if (gui_get_wide_font() == FAIL) errmsg = (char_u *)N_("E534: Invalid wide font"); + redraw_gui_only = TRUE; } # endif #endif @@ -6133,13 +6189,24 @@ #ifdef FEAT_GUI /* 'guioptions' */ else if (varp == &p_go) + { gui_init_which_components(oldval); + redraw_gui_only = TRUE; + } #endif #if defined(FEAT_GUI_TABLINE) /* 'guitablabel' */ else if (varp == &p_gtl) + { redraw_tabline = TRUE; + redraw_gui_only = TRUE; + } + /* 'guitabtooltip' */ + else if (varp == &p_gtt) + { + redraw_gui_only = TRUE; + } #endif #if defined(FEAT_MOUSE_TTY) && (defined(UNIX) || defined(VMS)) @@ -6717,7 +6784,11 @@ if (curwin->w_curswant != MAXCOL) curwin->w_set_curswant = TRUE; /* in case 'showbreak' changed */ - check_redraw(options[opt_idx].flags); +#ifdef FEAT_GUI + /* check redraw when it's not a GUI option or the GUI is active. */ + if (!redraw_gui_only || gui.in_use) +#endif + check_redraw(options[opt_idx].flags); return errmsg; } @@ -7105,22 +7176,28 @@ curbuf->b_did_warn = FALSE; #ifdef FEAT_TITLE - need_maketitle = TRUE; + redraw_titles(); #endif } #ifdef FEAT_TITLE /* when 'modifiable' is changed, redraw the window title */ else if ((int *)varp == &curbuf->b_p_ma) - need_maketitle = TRUE; + { + redraw_titles(); + } /* when 'endofline' is changed, redraw the window title */ else if ((int *)varp == &curbuf->b_p_eol) - need_maketitle = TRUE; -#ifdef FEAT_MBYTE - /* when 'bomb' is changed, redraw the window title */ + { + redraw_titles(); + } +# ifdef FEAT_MBYTE + /* when 'bomb' is changed, redraw the window title and tab page text */ else if ((int *)varp == &curbuf->b_p_bomb) - need_maketitle = TRUE; -#endif + { + redraw_titles(); + } +# endif #endif /* when 'bin' is set also set some other options */ @@ -7128,7 +7205,7 @@ { set_options_bin(old_value, curbuf->b_p_bin, opt_flags); #ifdef FEAT_TITLE - need_maketitle = TRUE; + redraw_titles(); #endif } @@ -7279,7 +7356,7 @@ if (!value) save_file_ff(curbuf); /* Buffer is unchanged */ #ifdef FEAT_TITLE - need_maketitle = TRUE; + redraw_titles(); #endif #ifdef FEAT_AUTOCMD modified_was_set = value; @@ -7486,9 +7563,13 @@ * set. */ if (STRCMP(p_enc, "utf-8") != 0) { + static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'"); + msg_source(hl_attr(HLF_W)); - MSG_ATTR(_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'"), - hl_attr(HLF_W)); + MSG_ATTR(_(w_arabic), hl_attr(HLF_W)); +#ifdef FEAT_EVAL + set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_arabic), -1); +#endif } # ifdef FEAT_MBYTE @@ -7714,7 +7795,7 @@ newFoldLevel(); } - /* 'foldminlevel' */ + /* 'foldminlines' */ else if (pp == &curwin->w_p_fml) { foldUpdateAll(curwin); @@ -7974,6 +8055,11 @@ else /* curwin->w_p_scr > curwin->w_height */ curwin->w_p_scr = curwin->w_height; } + if (p_hi < 0) + { + errmsg = e_positive; + p_hi = 0; + } if (p_report < 0) { errmsg = e_positive; @@ -8227,13 +8313,13 @@ { if (number == 0 && string != NULL) { - int index; + int idx; /* Either we are given a string or we are setting option * to zero. */ - for (index = 0; string[index] == '0'; ++index) + for (idx = 0; string[idx] == '0'; ++idx) ; - if (string[index] != NUL || index == 0) + if (string[idx] != NUL || idx == 0) { /* There's another character after zeros or the string * is empty. In both cases, we are trying to set a @@ -8323,7 +8409,7 @@ { --arg; /* put arg at the '<' */ modifiers = 0; - key = find_special_key(&arg, &modifiers, TRUE); + key = find_special_key(&arg, &modifiers, TRUE, TRUE); if (modifiers) /* can't handle modifiers here */ key = 0; } @@ -10093,25 +10179,110 @@ #ifdef FEAT_LANGMAP /* - * Any character has an equivalent character. This is used for keyboards that - * have a special language mode that sends characters above 128 (although - * other characters can be translated too). + * Any character has an equivalent 'langmap' character. This is used for + * keyboards that have a special language mode that sends characters above + * 128 (although other characters can be translated too). The "to" field is a + * Vim command character. This avoids having to switch the keyboard back to + * ASCII mode when leaving Insert mode. + * + * langmap_mapchar[] maps any of 256 chars to an ASCII char used for Vim + * commands. + * When FEAT_MBYTE is defined langmap_mapga.ga_data is a sorted table of + * langmap_entry_T. This does the same as langmap_mapchar[] for characters >= + * 256. + */ +# ifdef FEAT_MBYTE +/* + * With multi-byte support use growarray for 'langmap' chars >= 256 */ +typedef struct +{ + int from; + int to; +} langmap_entry_T; + +static garray_T langmap_mapga; +static void langmap_set_entry __ARGS((int from, int to)); /* - * char_u langmap_mapchar[256]; - * Normally maps each of the 128 upper chars to an <128 ascii char; used to - * "translate" native lang chars in normal mode or some cases of - * insert mode without having to tediously switch lang mode back&forth. + * Search for an entry in "langmap_mapga" for "from". If found set the "to" + * field. If not found insert a new entry at the appropriate location. */ + static void +langmap_set_entry(from, to) + int from; + int to; +{ + langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data); + int a = 0; + int b = langmap_mapga.ga_len; + + /* Do a binary search for an existing entry. */ + while (a != b) + { + int i = (a + b) / 2; + int d = entries[i].from - from; + + if (d == 0) + { + entries[i].to = to; + return; + } + if (d < 0) + a = i + 1; + else + b = i; + } + + if (ga_grow(&langmap_mapga, 1) != OK) + return; /* out of memory */ + + /* insert new entry at position "a" */ + entries = (langmap_entry_T *)(langmap_mapga.ga_data) + a; + mch_memmove(entries + 1, entries, + (langmap_mapga.ga_len - a) * sizeof(langmap_entry_T)); + ++langmap_mapga.ga_len; + entries[0].from = from; + entries[0].to = to; +} + +/* + * Apply 'langmap' to multi-byte character "c" and return the result. + */ + int +langmap_adjust_mb(c) + int c; +{ + langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data); + int a = 0; + int b = langmap_mapga.ga_len; + + while (a != b) + { + int i = (a + b) / 2; + int d = entries[i].from - c; + + if (d == 0) + return entries[i].to; /* found matching entry */ + if (d < 0) + a = i + 1; + else + b = i; + } + return c; /* no entry found, return "c" unmodified */ +} +# endif static void langmap_init() { int i; - for (i = 0; i < 256; i++) /* we init with a-one-to one map */ - langmap_mapchar[i] = i; + for (i = 0; i < 256; i++) + langmap_mapchar[i] = i; /* we init with a one-to-one map */ +# ifdef FEAT_MBYTE + ga_init2(&langmap_mapga, sizeof(langmap_entry_T), 8); +# endif } /* @@ -10125,7 +10296,10 @@ char_u *p2; int from, to; - langmap_init(); /* back to one-to-one map first */ +#ifdef FEAT_MBYTE + ga_clear(&langmap_mapga); /* clear the previous map first */ +#endif + langmap_init(); /* back to one-to-one map */ for (p = p_langmap; p[0] != NUL; ) { @@ -10175,7 +10349,13 @@ transchar(from)); return; } - langmap_mapchar[from & 255] = to; + +#ifdef FEAT_MBYTE + if (from >= 256) + langmap_set_entry(from, to); + else +#endif + langmap_mapchar[from & 255] = to; /* Advance to next pair */ mb_ptr_adv(p); diff -Naur vim72.orig/src/os_unix.c vim72/src/os_unix.c --- vim72.orig/src/os_unix.c 2008-08-06 04:01:40.000000000 -0700 +++ vim72/src/os_unix.c 2009-03-22 21:32:18.750505657 -0700 @@ -181,7 +181,8 @@ && defined(FEAT_TITLE) && !defined(FEAT_GUI_GTK) # define SET_SIG_ALARM static RETSIGTYPE sig_alarm __ARGS(SIGPROTOARG); -static int sig_alarm_called; +/* volatile because it is used in signal handler sig_alarm(). */ +static volatile int sig_alarm_called; #endif static RETSIGTYPE deathtrap __ARGS(SIGPROTOARG); @@ -201,13 +202,16 @@ # define SIG_ERR ((RETSIGTYPE (*)())-1) #endif -static int do_resize = FALSE; +/* volatile because it is used in signal handler sig_winch(). */ +static volatile int do_resize = FALSE; #ifndef __EMX__ static char_u *extra_shell_arg = NULL; static int show_shell_mess = TRUE; #endif -static int deadly_signal = 0; /* The signal we caught */ -static int in_mch_delay = FALSE; /* sleeping in mch_delay() */ +/* volatile because it is used in signal handler deathtrap(). */ +static volatile int deadly_signal = 0; /* The signal we caught */ +/* volatile because it is used in signal handler deathtrap(). */ +static volatile int in_mch_delay = FALSE; /* sleeping in mch_delay() */ static int curr_tmode = TMODE_COOK; /* contains current terminal mode */ @@ -315,12 +319,15 @@ {-1, "Unknown!", FALSE} }; +/* + * Write s[len] to the screen. + */ void mch_write(s, len) char_u *s; int len; { - write(1, (char *)s, len); + ignored = (int)write(1, (char *)s, len); if (p_wd) /* Unix is too fast, slow down a bit more */ RealWaitForChar(read_cmd_fd, p_wd, NULL); } @@ -799,7 +806,7 @@ #endif /* - * We need correct potatotypes for a signal function, otherwise mean compilers + * We need correct prototypes for a signal function, otherwise mean compilers * will barf when the second argument to signal() is ``wrong''. * Let me try it with a few tricky defines from my own osdef.h (jw). */ @@ -1065,13 +1072,18 @@ SIGRETURN; } -#ifdef _REENTRANT +#if defined(_REENTRANT) && defined(SIGCONT) /* * On Solaris with multi-threading, suspending might not work immediately. * Catch the SIGCONT signal, which will be used as an indication whether the * suspending has been done or not. + * + * On Linux, signal is not always handled immediately either. + * See https://bugs.launchpad.net/bugs/291373 + * + * volatile because it is used in in signal handler sigcont_handler(). */ -static int sigcont_received; +static volatile int sigcont_received; static RETSIGTYPE sigcont_handler __ARGS(SIGPROTOARG); /* @@ -1115,15 +1127,28 @@ } # endif -# ifdef _REENTRANT +# if defined(_REENTRANT) && defined(SIGCONT) sigcont_received = FALSE; # endif kill(0, SIGTSTP); /* send ourselves a STOP signal */ -# ifdef _REENTRANT - /* When we didn't suspend immediately in the kill(), do it now. Happens - * on multi-threaded Solaris. */ - if (!sigcont_received) - pause(); +# if defined(_REENTRANT) && defined(SIGCONT) + /* + * Wait for the SIGCONT signal to be handled. It generally happens + * immediately, but somehow not all the time. Do not call pause() + * because there would be race condition which would hang Vim if + * signal happened in between the test of sigcont_received and the + * call to pause(). If signal is not yet received, call sleep(0) + * to just yield CPU. Signal should then be received. If somehow + * it's still not received, sleep 1, 2, 3 ms. Don't bother waiting + * further if signal is not received after 1+2+3+4 ms (not expected + * to happen). + */ + { + long wait; + for (wait = 0; !sigcont_received && wait <= 3L; wait++) + /* Loop is not entered most of the time */ + mch_delay(wait, FALSE); + } # endif # ifdef FEAT_TITLE @@ -1172,7 +1197,7 @@ #ifdef SIGTSTP signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL); #endif -#ifdef _REENTRANT +#if defined(_REENTRANT) && defined(SIGCONT) signal(SIGCONT, sigcont_handler); #endif @@ -1231,7 +1256,7 @@ reset_signals() { catch_signals(SIG_DFL, SIG_DFL); -#ifdef _REENTRANT +#if defined(_REENTRANT) && defined(SIGCONT) /* SIGCONT isn't in the list, because its default action is ignore */ signal(SIGCONT, SIG_DFL); #endif @@ -2905,7 +2930,7 @@ * Ignore any errors. */ #if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK) - signal_stack = malloc(SIGSTKSZ); + signal_stack = (char *)alloc(SIGSTKSZ); init_signal_stack(); #endif } @@ -2936,7 +2961,8 @@ } # endif # endif -# ifdef FEAT_X11 + /* Don't close the display for GTK 1, it is done in exit(). */ +# if defined(FEAT_X11) && (!defined(FEAT_GUI_GTK) || defined(HAVE_GTK2)) if (x11_display != NULL # ifdef FEAT_XCLIPBOARD && x11_display != xterm_dpy @@ -3926,9 +3952,9 @@ */ if (fd >= 0) { - dup(fd); /* To replace stdin (file descriptor 0) */ - dup(fd); /* To replace stdout (file descriptor 1) */ - dup(fd); /* To replace stderr (file descriptor 2) */ + ignored = dup(fd); /* To replace stdin (fd 0) */ + ignored = dup(fd); /* To replace stdout (fd 1) */ + ignored = dup(fd); /* To replace stderr (fd 2) */ /* Don't need this now that we've duplicated it */ close(fd); @@ -3946,7 +3972,17 @@ * children can be kill()ed. Don't do this when using pipes, * because stdin is not a tty, we would lose /dev/tty. */ if (p_stmp) + { (void)setsid(); +# if defined(SIGHUP) + /* When doing "!xterm&" and 'shell' is bash: the shell + * will exit and send SIGHUP to all processes in its + * group, killing the just started process. Ignore SIGHUP + * to avoid that. (suggested by Simon Schubert) + */ + signal(SIGHUP, SIG_IGN); +# endif + } # endif # ifdef FEAT_GUI if (pty_slave_fd >= 0) @@ -3996,13 +4032,13 @@ /* set up stdin/stdout/stderr for the child */ close(0); - dup(pty_slave_fd); + ignored = dup(pty_slave_fd); close(1); - dup(pty_slave_fd); + ignored = dup(pty_slave_fd); if (gui.in_use) { close(2); - dup(pty_slave_fd); + ignored = dup(pty_slave_fd); } close(pty_slave_fd); /* has been dupped, close it now */ @@ -4013,13 +4049,13 @@ /* set up stdin for the child */ close(fd_toshell[1]); close(0); - dup(fd_toshell[0]); + ignored = dup(fd_toshell[0]); close(fd_toshell[0]); /* set up stdout for the child */ close(fd_fromshell[0]); close(1); - dup(fd_fromshell[1]); + ignored = dup(fd_fromshell[1]); close(fd_fromshell[1]); # ifdef FEAT_GUI @@ -4027,7 +4063,7 @@ { /* set up stderr for the child */ close(2); - dup(1); + ignored = dup(1); } # endif } @@ -4078,6 +4114,9 @@ int fromshell_fd; garray_T ga; int noread_cnt; +# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) + struct timeval start_tv; +# endif # ifdef FEAT_GUI if (pty_master_fd >= 0) @@ -4158,7 +4197,8 @@ && (lnum != curbuf->b_ml.ml_line_count || curbuf->b_p_eol))) - write(toshell_fd, "\n", (size_t)1); + ignored = write(toshell_fd, "\n", + (size_t)1); ++lnum; if (lnum > curbuf->b_op_end.lnum) { @@ -4186,7 +4226,9 @@ ga_init2(&ga, 1, BUFLEN); noread_cnt = 0; - +# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) + gettimeofday(&start_tv, NULL); +# endif for (;;) { /* @@ -4199,25 +4241,34 @@ * that a typed password is echoed for ssh or gpg command. * Don't get characters when the child has already * finished (wait_pid == 0). - * Don't get extra characters when we already have one. * Don't read characters unless we didn't get output for a - * while, avoids that ":r !ls" eats typeahead. + * while (noread_cnt > 4), avoids that ":r !ls" eats + * typeahead. */ len = 0; if (!(options & SHELL_EXPAND) && ((options & (SHELL_READ|SHELL_WRITE|SHELL_COOKED)) != (SHELL_READ|SHELL_WRITE|SHELL_COOKED) -#ifdef FEAT_GUI +# ifdef FEAT_GUI || gui.in_use -#endif +# endif ) && wait_pid == 0 - && (ta_len > 0 - || (noread_cnt > 4 - && (len = ui_inchar(ta_buf, - BUFLEN, 10L, 0)) > 0))) + && (ta_len > 0 || noread_cnt > 4)) { + if (ta_len == 0) + { + /* Get extra characters when we don't have any. + * Reset the counter and timer. */ + noread_cnt = 0; +# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) + gettimeofday(&start_tv, NULL); +# endif + len = ui_inchar(ta_buf, BUFLEN, 10L, 0); + } + if (ta_len > 0 || len > 0) + { /* * For pipes: * Check for CTRL-C: send interrupt signal to child. @@ -4319,9 +4370,9 @@ { ta_len -= len; mch_memmove(ta_buf, ta_buf + len, ta_len); - noread_cnt = 0; } } + } } if (got_int) @@ -4429,6 +4480,25 @@ out_flush(); if (got_int) break; + +# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) + { + struct timeval now_tv; + long msec; + + /* Avoid that we keep looping here without + * checking for a CTRL-C for a long time. Don't + * break out too often to avoid losing typeahead. */ + gettimeofday(&now_tv, NULL); + msec = (now_tv.tv_sec - start_tv.tv_sec) * 1000L + + (now_tv.tv_usec - start_tv.tv_usec) / 1000L; + if (msec > 2000) + { + noread_cnt = 5; + break; + } + } +# endif } /* If we already detected the child has finished break the @@ -5851,7 +5921,9 @@ * we are going to suspend or starting an external process * so we shouldn't have problem with this */ +# ifdef SIGTSTP signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL); +# endif return 1; /* succeed */ } if (gpm_fd == -2) @@ -6814,7 +6886,8 @@ if (xsmp_icefd != -1) { SmcCloseConnection(xsmp.smcconn, 0, NULL); - vim_free(xsmp.clientid); + if (xsmp.clientid != NULL) + free(xsmp.clientid); xsmp.clientid = NULL; xsmp_icefd = -1; } diff -Naur vim72.orig/src/proto/eval.pro vim72/src/proto/eval.pro --- vim72.orig/src/proto/eval.pro 2008-08-09 07:31:25.000000000 -0700 +++ vim72/src/proto/eval.pro 2009-03-22 21:28:55.169458863 -0700 @@ -17,7 +17,7 @@ int eval_to_bool __ARGS((char_u *arg, int *error, char_u **nextcmd, int skip)); char_u *eval_to_string_skip __ARGS((char_u *arg, char_u **nextcmd, int skip)); int skip_expr __ARGS((char_u **pp)); -char_u *eval_to_string __ARGS((char_u *arg, char_u **nextcmd, int dolist)); +char_u *eval_to_string __ARGS((char_u *arg, char_u **nextcmd, int convert)); char_u *eval_to_string_safe __ARGS((char_u *arg, char_u **nextcmd, int use_sandbox)); int eval_to_number __ARGS((char_u *expr)); list_T *eval_spell_expr __ARGS((char_u *badword, char_u *expr)); @@ -46,7 +46,9 @@ void list_unref __ARGS((list_T *l)); void list_free __ARGS((list_T *l, int recurse)); dictitem_T *dict_lookup __ARGS((hashitem_T *hi)); +char_u *list_find_str __ARGS((list_T *l, long idx)); int list_append_dict __ARGS((list_T *list, dict_T *dict)); +int list_append_string __ARGS((list_T *l, char_u *str, int len)); int garbage_collect __ARGS((void)); dict_T *dict_alloc __ARGS((void)); int dict_add_nr_str __ARGS((dict_T *d, char *key, long nr, char_u *str)); @@ -58,8 +60,10 @@ void set_vim_var_nr __ARGS((int idx, long val)); long get_vim_var_nr __ARGS((int idx)); char_u *get_vim_var_str __ARGS((int idx)); -void set_vcount __ARGS((long count, long count1)); +list_T *get_vim_var_list __ARGS((int idx)); +void set_vcount __ARGS((long count, long count1, int set_prevcount)); void set_vim_var_string __ARGS((int idx, char_u *val, int len)); +void set_vim_var_list __ARGS((int idx, list_T *val)); void set_reg_var __ARGS((int c)); char_u *v_exception __ARGS((char_u *oldval)); char_u *v_throwpoint __ARGS((char_u *oldval)); @@ -94,6 +98,7 @@ void write_viminfo_varlist __ARGS((FILE *fp)); int store_session_globals __ARGS((FILE *fd)); void last_set_msg __ARGS((scid_T scriptID)); +void ex_oldfiles __ARGS((exarg_T *eap)); int modify_fname __ARGS((char_u *src, int *usedlen, char_u **fnamep, char_u **bufp, int *fnamelen)); char_u *do_string_sub __ARGS((char_u *str, char_u *pat, char_u *sub, char_u *flags)); /* vim: set ft=c : */ diff -Naur vim72.orig/src/proto/ex_cmds.pro vim72/src/proto/ex_cmds.pro --- vim72.orig/src/proto/ex_cmds.pro 2008-08-09 07:31:25.000000000 -0700 +++ vim72/src/proto/ex_cmds.pro 2009-03-22 21:32:08.697861154 -0700 @@ -11,7 +11,7 @@ char_u *make_filter_cmd __ARGS((char_u *cmd, char_u *itmp, char_u *otmp)); void append_redir __ARGS((char_u *buf, char_u *opt, char_u *fname)); int viminfo_error __ARGS((char *errnum, char *message, char_u *line)); -int read_viminfo __ARGS((char_u *file, int want_info, int want_marks, int forceit)); +int read_viminfo __ARGS((char_u *file, int flags)); void write_viminfo __ARGS((char_u *file, int forceit)); int viminfo_readline __ARGS((vir_T *virp)); char_u *viminfo_readstring __ARGS((vir_T *virp, int off, int convert)); @@ -40,6 +40,7 @@ int read_viminfo_sub_string __ARGS((vir_T *virp, int force)); void write_viminfo_sub_string __ARGS((FILE *fp)); void free_old_sub __ARGS((void)); +void free_signs __ARGS((void)); int prepare_tagpreview __ARGS((int undo_sync)); void ex_help __ARGS((exarg_T *eap)); char_u *check_help_lang __ARGS((char_u *arg)); diff -Naur vim72.orig/src/proto/ex_getln.pro vim72/src/proto/ex_getln.pro --- vim72.orig/src/proto/ex_getln.pro 2008-08-09 07:31:28.000000000 -0700 +++ vim72/src/proto/ex_getln.pro 2009-03-22 21:32:23.786828608 -0700 @@ -4,6 +4,7 @@ int text_locked __ARGS((void)); void text_locked_msg __ARGS((void)); int curbuf_locked __ARGS((void)); +int allbuf_locked __ARGS((void)); char_u *getexline __ARGS((int c, void *dummy, int indent)); char_u *getexmodeline __ARGS((int promptc, void *dummy, int indent)); int cmdline_overstrike __ARGS((void)); @@ -31,7 +32,7 @@ void set_cmd_context __ARGS((expand_T *xp, char_u *str, int len, int col)); int expand_cmdline __ARGS((expand_T *xp, char_u *str, int col, int *matchcount, char_u ***matches)); int ExpandGeneric __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file, char_u *((*func)(expand_T *, int)))); -char_u *globpath __ARGS((char_u *path, char_u *file)); +char_u *globpath __ARGS((char_u *path, char_u *file, int expand_options)); void init_history __ARGS((void)); int get_histtype __ARGS((char_u *name)); void add_to_history __ARGS((int histype, char_u *new_entry, int in_map, int sep)); diff -Naur vim72.orig/src/proto/if_cscope.pro vim72/src/proto/if_cscope.pro --- vim72.orig/src/proto/if_cscope.pro 2008-08-09 07:31:33.000000000 -0700 +++ vim72/src/proto/if_cscope.pro 2009-03-22 21:32:51.512605113 -0700 @@ -1,4 +1,6 @@ /* if_cscope.c */ +char_u *get_cscope_name __ARGS((expand_T *xp, int idx)); +void set_context_in_cscope_cmd __ARGS((expand_T *xp, char_u *arg)); void do_cscope __ARGS((exarg_T *eap)); void do_scscope __ARGS((exarg_T *eap)); void do_cstag __ARGS((exarg_T *eap)); diff -Naur vim72.orig/src/proto/mark.pro vim72/src/proto/mark.pro --- vim72.orig/src/proto/mark.pro 2008-08-09 07:31:36.000000000 -0700 +++ vim72/src/proto/mark.pro 2009-03-22 21:28:12.902752340 -0700 @@ -26,5 +26,5 @@ void write_viminfo_filemarks __ARGS((FILE *fp)); int removable __ARGS((char_u *name)); int write_viminfo_marks __ARGS((FILE *fp_out)); -void copy_viminfo_marks __ARGS((vir_T *virp, FILE *fp_out, int count, int eof)); +void copy_viminfo_marks __ARGS((vir_T *virp, FILE *fp_out, int count, int eof, int flags)); /* vim: set ft=c : */ diff -Naur vim72.orig/src/proto/misc2.pro vim72/src/proto/misc2.pro --- vim72.orig/src/proto/misc2.pro 2008-08-09 07:31:40.000000000 -0700 +++ vim72/src/proto/misc2.pro 2009-03-22 21:29:58.829540160 -0700 @@ -59,7 +59,7 @@ int handle_x_keys __ARGS((int key)); char_u *get_special_key_name __ARGS((int c, int modifiers)); int trans_special __ARGS((char_u **srcp, char_u *dst, int keycode)); -int find_special_key __ARGS((char_u **srcp, int *modp, int keycode)); +int find_special_key __ARGS((char_u **srcp, int *modp, int keycode, int keep_x_key)); int extract_modifiers __ARGS((int key, int *modp)); int find_special_key_in_table __ARGS((int c)); int get_special_key_code __ARGS((char_u *name)); diff -Naur vim72.orig/src/proto/netbeans.pro vim72/src/proto/netbeans.pro --- vim72.orig/src/proto/netbeans.pro 2008-08-09 07:31:56.000000000 -0700 +++ vim72/src/proto/netbeans.pro 2009-03-22 21:30:13.578485264 -0700 @@ -11,7 +11,7 @@ void netbeans_frame_moved __ARGS((int new_x, int new_y)); void netbeans_file_activated __ARGS((buf_T *bufp)); void netbeans_file_opened __ARGS((buf_T *bufp)); -void netbeans_file_closed __ARGS((buf_T *bufp)); +void netbeans_file_killed __ARGS((buf_T *bufp)); void netbeans_inserted __ARGS((buf_T *bufp, linenr_T linenr, colnr_T col, char_u *txt, int newlen)); void netbeans_removed __ARGS((buf_T *bufp, linenr_T linenr, colnr_T col, long len)); void netbeans_unmodified __ARGS((buf_T *bufp)); diff -Naur vim72.orig/src/proto/option.pro vim72/src/proto/option.pro --- vim72.orig/src/proto/option.pro 2008-08-09 07:31:43.000000000 -0700 +++ vim72/src/proto/option.pro 2009-03-22 21:31:27.239205476 -0700 @@ -44,6 +44,7 @@ void set_context_in_set_cmd __ARGS((expand_T *xp, char_u *arg, int opt_flags)); int ExpandSettings __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file)); int ExpandOldSetting __ARGS((int *num_file, char_u ***file)); +int langmap_adjust_mb __ARGS((int c)); int has_format_option __ARGS((int x)); int shortmess __ARGS((int x)); void vimrc_found __ARGS((char_u *fname, char_u *envname)); diff -Naur vim72.orig/src/pty.c vim72/src/pty.c --- vim72.orig/src/pty.c 2008-06-21 11:52:58.000000000 -0700 +++ vim72/src/pty.c 2009-03-22 21:26:57.485917865 -0700 @@ -270,9 +270,10 @@ } #endif -#if defined(HAVE_SVR4_PTYS) && !defined(PTY_DONE) && !defined(hpux) +#if defined(HAVE_SVR4_PTYS) && !defined(PTY_DONE) && !defined(hpux) && !defined(MACOS_X) -/* NOTE: Even though HPUX can have /dev/ptmx, the code below doesn't work! */ +/* NOTE: Even though HPUX can have /dev/ptmx, the code below doesn't work! + * Same for Mac OS X Leopard. */ #define PTY_DONE int OpenPTY(ttyn) diff -Naur vim72.orig/src/quickfix.c vim72/src/quickfix.c --- vim72.orig/src/quickfix.c 2008-07-18 05:53:02.000000000 -0700 +++ vim72/src/quickfix.c 2009-03-22 21:31:54.128927784 -0700 @@ -1419,6 +1419,7 @@ int opened_window = FALSE; win_T *win; win_T *altwin; + int flags; #endif int print_message = TRUE; int len; @@ -1530,7 +1531,6 @@ if (qf_ptr->qf_type == 1 && (!curwin->w_buffer->b_help || cmdmod.tab != 0)) { win_T *wp; - int n; if (cmdmod.tab != 0) wp = NULL; @@ -1546,13 +1546,16 @@ * Split off help window; put it at far top if no position * specified, the current window is vertically split and narrow. */ - n = WSP_HELP; + flags = WSP_HELP; # ifdef FEAT_VERTSPLIT if (cmdmod.split == 0 && curwin->w_width != Columns && curwin->w_width < 80) - n |= WSP_TOP; + flags |= WSP_TOP; # endif - if (win_split(0, n) == FAIL) + if (qi != &ql_info) + flags |= WSP_NEWLOC; /* don't copy the location list */ + + if (win_split(0, flags) == FAIL) goto theend; opened_window = TRUE; /* close it when fail */ @@ -1562,7 +1565,6 @@ if (qi != &ql_info) /* not a quickfix list */ { /* The new window should use the supplied location list */ - qf_free_all(curwin); curwin->w_llist = qi; qi->qf_refcount++; } @@ -1609,10 +1611,11 @@ { goto_tabpage_win(tp, wp); usable_win = 1; - break; + goto win_found; } } } +win_found: /* * If there is only one window and it is the quickfix window, create a @@ -1622,7 +1625,10 @@ { ll_ref = curwin->w_llist_ref; - if (win_split(0, WSP_ABOVE) == FAIL) + flags = WSP_ABOVE; + if (ll_ref != NULL) + flags |= WSP_NEWLOC; + if (win_split(0, flags) == FAIL) goto failed; /* not enough room for window */ opened_window = TRUE; /* close it when fail */ p_swb = empty_option; /* don't split again */ @@ -1634,7 +1640,6 @@ { /* The new window should use the location list from the * location list window */ - qf_free_all(curwin); curwin->w_llist = ll_ref; ll_ref->qf_refcount++; } @@ -2307,15 +2312,12 @@ if (eap->cmdidx == CMD_copen || eap->cmdidx == CMD_cwindow) /* Create the new window at the very bottom. */ win_goto(lastwin); - if (win_split(height, WSP_BELOW) == FAIL) + if (win_split(height, WSP_BELOW | WSP_NEWLOC) == FAIL) return; /* not enough room for window */ #ifdef FEAT_SCROLLBIND curwin->w_p_scb = FALSE; #endif - /* Remove the location list for the quickfix window */ - qf_free_all(curwin); - if (eap->cmdidx == CMD_lopen || eap->cmdidx == CMD_lwindow) { /* diff -Naur vim72.orig/src/regexp.c vim72/src/regexp.c --- vim72.orig/src/regexp.c 2008-08-07 12:58:50.000000000 -0700 +++ vim72/src/regexp.c 2009-03-22 21:31:36.967828468 -0700 @@ -4532,7 +4532,7 @@ cleanup_subexpr(); if (!REG_MULTI) /* Single-line regexp */ { - if (reg_endp[no] == NULL) + if (reg_startp[no] == NULL || reg_endp[no] == NULL) { /* Backref was not set: Match an empty string. */ len = 0; @@ -4548,7 +4548,7 @@ } else /* Multi-line regexp */ { - if (reg_endpos[no].lnum < 0) + if (reg_startpos[no].lnum < 0 || reg_endpos[no].lnum < 0) { /* Backref was not set: Match an empty string. */ len = 0; @@ -7279,13 +7279,11 @@ } else { - if (submatch_match->endp[no] == NULL) + s = submatch_match->startp[no]; + if (s == NULL || submatch_match->endp[no] == NULL) retval = NULL; else - { - s = submatch_match->startp[no]; retval = vim_strnsave(s, (int)(submatch_match->endp[no] - s)); - } } return retval; diff -Naur vim72.orig/src/screen.c vim72/src/screen.c --- vim72.orig/src/screen.c 2008-07-24 07:45:07.000000000 -0700 +++ vim72/src/screen.c 2009-03-22 21:33:03.705385948 -0700 @@ -2439,9 +2439,17 @@ #ifdef FEAT_SYN_HL /* Show 'cursorcolumn' in the fold line. */ - if (wp->w_p_cuc && (int)wp->w_virtcol + txtcol < W_WIDTH(wp)) - ScreenAttrs[off + wp->w_virtcol + txtcol] = hl_combine_attr( - ScreenAttrs[off + wp->w_virtcol + txtcol], hl_attr(HLF_CUC)); + if (wp->w_p_cuc) + { + txtcol += wp->w_virtcol; + if (wp->w_p_wrap) + txtcol -= wp->w_skipcol; + else + txtcol -= wp->w_leftcol; + if (txtcol >= 0 && txtcol < W_WIDTH(wp)) + ScreenAttrs[off + txtcol] = hl_combine_attr( + ScreenAttrs[off + txtcol], hl_attr(HLF_CUC)); + } #endif SCREEN_LINE(row + W_WINROW(wp), W_WINCOL(wp), (int)W_WIDTH(wp), @@ -2588,6 +2596,7 @@ int noinvcur = FALSE; /* don't invert the cursor */ #ifdef FEAT_VISUAL pos_T *top, *bot; + int lnum_in_visual_area = FALSE; #endif pos_T pos; long v; @@ -2784,9 +2793,10 @@ top = &VIsual; bot = &curwin->w_cursor; } + lnum_in_visual_area = (lnum >= top->lnum && lnum <= bot->lnum); if (VIsual_mode == Ctrl_V) /* block mode */ { - if (lnum >= top->lnum && lnum <= bot->lnum) + if (lnum_in_visual_area) { fromcol = wp->w_old_cursor_fcol; tocol = wp->w_old_cursor_lcol; @@ -2879,8 +2889,9 @@ } else tocol = MAXCOL; - if (fromcol == tocol) /* do at least one character */ - tocol = fromcol + 1; /* happens when past end of line */ + /* do at least one character; happens when past end of line */ + if (fromcol == tocol) + tocol = fromcol + 1; area_highlighting = TRUE; attr = hl_attr(HLF_I); } @@ -3412,6 +3423,7 @@ && (*mb_ptr2cells)(ptr) > 1) #endif || ((int)vcol_prev == fromcol_prev + && vcol_prev < vcol /* not at margin */ && vcol < tocol)) area_attr = attr; /* start highlighting */ else if (area_attr != 0 @@ -3544,7 +3556,8 @@ /* Use line_attr when not in the Visual or 'incsearch' area * (area_attr may be 0 when "noinvcur" is set). */ else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL) - || (vcol < fromcol || vcol >= tocol))) + || vcol < fromcol || vcol_prev < fromcol_prev + || vcol >= tocol)) char_attr = line_attr; #endif else @@ -4106,6 +4119,7 @@ # endif (col < W_WIDTH(wp))) && !(noinvcur + && lnum == wp->w_cursor.lnum && (colnr_T)vcol == wp->w_virtcol))) && lcs_eol_one >= 0) { @@ -4247,7 +4261,7 @@ * preedit_changed and commit. Thus Vim can't set "im_is_active", use * im_is_preediting() here. */ if (xic != NULL - && lnum == curwin->w_cursor.lnum + && lnum == wp->w_cursor.lnum && (State & INSERT) && !p_imdisable && im_is_preediting() @@ -4256,7 +4270,7 @@ colnr_T tcol; if (preedit_end_col == MAXCOL) - getvcol(curwin, &(curwin->w_cursor), &tcol, NULL, NULL); + getvcol(curwin, &(wp->w_cursor), &tcol, NULL, NULL); else tcol = preedit_end_col; if ((long)preedit_start_col <= vcol && vcol < (long)tcol) @@ -4353,7 +4367,13 @@ } #endif if (lcs_eol == lcs_eol_one - && ((area_attr != 0 && vcol == fromcol && c == NUL) + && ((area_attr != 0 && vcol == fromcol +#ifdef FEAT_VISUAL + && (VIsual_mode != Ctrl_V + || lnum == VIsual.lnum + || lnum == curwin->w_cursor.lnum) +#endif + && c == NUL) #ifdef FEAT_SEARCH_EXTRA /* highlight 'hlsearch' match at end of line */ || (prevcol_hl_flag == TRUE @@ -4447,7 +4467,8 @@ if (c == NUL) { #ifdef FEAT_SYN_HL - if (eol_hl_off > 0 && vcol - eol_hl_off == (long)wp->w_virtcol) + if (eol_hl_off > 0 && vcol - eol_hl_off == (long)wp->w_virtcol + && lnum == wp->w_cursor.lnum) { /* highlight last char after line */ --col; @@ -4549,7 +4570,8 @@ * highlight the cursor position itself. */ if (wp->w_p_cuc && vcol == (long)wp->w_virtcol && lnum != wp->w_cursor.lnum - && draw_state == WL_LINE) + && draw_state == WL_LINE + && !lnum_in_visual_area) { vcol_save_attr = char_attr; char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUC)); @@ -4652,7 +4674,7 @@ --n_skip; /* Only advance the "vcol" when after the 'number' column. */ - if (draw_state >= WL_SBR + if (draw_state > WL_NR #ifdef FEAT_DIFF && filler_todo <= 0 #endif @@ -5119,8 +5141,8 @@ #endif #if defined(FEAT_GUI) || defined(UNIX) - /* The bold trick makes a single row of pixels appear in the next - * character. When a bold character is removed, the next + /* The bold trick makes a single column of pixels appear in the + * next character. When a bold character is removed, the next * character should be redrawn too. This happens for our own GUI * and for some xterms. */ if ( @@ -6263,9 +6285,15 @@ int pcc[MAX_MCO]; # endif #endif +#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX) + int force_redraw_this; + int force_redraw_next = FALSE; +#endif + int need_redraw; if (ScreenLines == NULL || row >= screen_Rows) /* safety check */ return; + off = LineOffset[row] + col; #ifdef FEAT_MBYTE /* When drawing over the right halve of a double-wide char clear out the @@ -6275,10 +6303,21 @@ && !gui.in_use # endif && mb_fix_col(col, row) != col) - screen_puts_len((char_u *)" ", 1, row, col - 1, 0); + { + ScreenLines[off - 1] = ' '; + ScreenAttrs[off - 1] = 0; + if (enc_utf8) + { + ScreenLinesUC[off - 1] = 0; + ScreenLinesC[0][off - 1] = 0; + } + /* redraw the previous cell, make it empty */ + screen_char(off - 1, row, col - 1); + /* force the cell at "col" to be redrawn */ + force_redraw_next = TRUE; + } #endif - off = LineOffset[row] + col; #ifdef FEAT_MBYTE max_off = LineOffset[row] + screen_Columns; #endif @@ -6342,7 +6381,12 @@ } #endif - if (ScreenLines[off] != c +#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX) + force_redraw_this = force_redraw_next; + force_redraw_next = FALSE; +#endif + + need_redraw = ScreenLines[off] != c #ifdef FEAT_MBYTE || (mbyte_cells == 2 && ScreenLines[off + 1] != (enc_dbcs ? ptr[1] : 0)) @@ -6350,24 +6394,24 @@ && c == 0x8e && ScreenLines2[off] != ptr[1]) || (enc_utf8 - && (ScreenLinesUC[off] != (u8char_T)u8c + && (ScreenLinesUC[off] != (u8char_T)(c >= 0x80 ? u8c : 0) || screen_comp_differs(off, u8cc))) #endif || ScreenAttrs[off] != attr - || exmode_active + || exmode_active; + + if (need_redraw +#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX) + || force_redraw_this +#endif ) { #if defined(FEAT_GUI) || defined(UNIX) /* The bold trick makes a single row of pixels appear in the next * character. When a bold character is removed, the next * character should be redrawn too. This happens for our own GUI - * and for some xterms. - * Force the redraw by setting the attribute to a different value - * than "attr", the contents of ScreenLines[] may be needed by - * mb_off2cells() further on. - * Don't do this for the last drawn character, because the next - * character may not be redrawn. */ - if ( + * and for some xterms. */ + if (need_redraw && ScreenLines[off] != ' ' && ( # ifdef FEAT_GUI gui.in_use # endif @@ -6377,23 +6421,14 @@ # ifdef UNIX term_is_xterm # endif - ) + )) { - int n; + int n = ScreenAttrs[off]; - n = ScreenAttrs[off]; -# ifdef FEAT_MBYTE - if (col + mbyte_cells < screen_Columns - && (n > HL_ALL || (n & HL_BOLD)) - && (len < 0 ? ptr[mbyte_blen] != NUL - : ptr + mbyte_blen < text + len)) - ScreenAttrs[off + mbyte_cells] = attr + 1; -# else - if (col + 1 < screen_Columns - && (n > HL_ALL || (n & HL_BOLD)) - && (len < 0 ? ptr[1] != NUL : ptr + 1 < text + len)) - ScreenLines[off + 1] = 0; -# endif + if (n > HL_ALL) + n = syn_attr2attr(n); + if (n & HL_BOLD) + force_redraw_next = TRUE; } #endif #ifdef FEAT_MBYTE @@ -6480,6 +6515,20 @@ ++ptr; } } + +#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX) + /* If we detected the next character needs to be redrawn, but the text + * doesn't extend up to there, update the character here. */ + if (force_redraw_next && col < screen_Columns) + { +# ifdef FEAT_MBYTE + if (enc_dbcs != 0 && dbcs_off2cells(off, max_off) > 1) + screen_char_2(off, row, col); + else +# endif + screen_char(off, row, col); + } +#endif } #ifdef FEAT_SEARCH_EXTRA @@ -7356,7 +7405,11 @@ #endif static int entered = FALSE; /* avoid recursiveness */ static int done_outofmem_msg = FALSE; /* did outofmem message */ +#ifdef FEAT_AUTOCMD + int retry_count = 0; +retry: +#endif /* * Allocation of the screen buffers is done only when the size changes and * when Rows and Columns have been set and we have started doing full @@ -7440,10 +7493,13 @@ { outofmem = TRUE; #ifdef FEAT_WINDOWS - break; + goto give_up; #endif } } +#ifdef FEAT_WINDOWS +give_up: +#endif #ifdef FEAT_MBYTE for (i = 0; i < p_mco; ++i) @@ -7628,8 +7684,17 @@ --RedrawingDisabled; #ifdef FEAT_AUTOCMD - if (starting == 0) + /* + * Do not apply autocommands more than 3 times to avoid an endless loop + * in case applying autocommands always changes Rows or Columns. + */ + if (starting == 0 && ++retry_count <= 3) + { apply_autocmds(EVENT_VIMRESIZED, NULL, NULL, FALSE, curbuf); + /* In rare cases, autocommands may have altered Rows or Columns, + * jump back to check if we need to allocate the screen again. */ + goto retry; + } #endif } diff -Naur vim72.orig/src/spell.c vim72/src/spell.c --- vim72.orig/src/spell.c 2008-07-12 12:20:55.000000000 -0700 +++ vim72/src/spell.c 2009-03-22 21:31:19.602716022 -0700 @@ -77,7 +77,7 @@ /* * Do the opposite: based on a maximum end score and a known sound score, - * compute the the maximum word score that can be used. + * compute the maximum word score that can be used. */ #define MAXSCORE(word_score, sound_score) ((4 * word_score - sound_score) / 3) @@ -469,6 +469,7 @@ garray_T sl_comppat; /* CHECKCOMPOUNDPATTERN items */ regprog_T *sl_compprog; /* COMPOUNDRULE turned into a regexp progrm * (NULL when no compounding) */ + char_u *sl_comprules; /* all COMPOUNDRULE concatenated (or NULL) */ char_u *sl_compstartflags; /* flags for first compound word */ char_u *sl_compallflags; /* all flags for compound words */ char_u sl_nobreak; /* When TRUE: no spaces between words */ @@ -625,7 +626,7 @@ /* TRUE if a word appears in the list of banned words. */ #define WAS_BANNED(su, word) (!HASHITEM_EMPTY(hash_find(&su->su_banned, word))) -/* Number of suggestions kept when cleaning up. we need to keep more than +/* Number of suggestions kept when cleaning up. We need to keep more than * what is displayed, because when rescore_suggestions() is called the score * may change and wrong suggestions may be removed later. */ #define SUG_CLEAN_COUNT(su) ((su)->su_maxcount < 130 ? 150 : (su)->su_maxcount + 20) @@ -839,7 +840,10 @@ static void slang_clear __ARGS((slang_T *lp)); static void slang_clear_sug __ARGS((slang_T *lp)); static void find_word __ARGS((matchinf_T *mip, int mode)); +static int match_checkcompoundpattern __ARGS((char_u *ptr, int wlen, garray_T *gap)); static int can_compound __ARGS((slang_T *slang, char_u *word, char_u *flags)); +static int can_be_compound __ARGS((trystate_T *sp, slang_T *slang, char_u *compflags, int flag)); +static int match_compoundrule __ARGS((slang_T *slang, char_u *compflags)); static int valid_word_prefix __ARGS((int totprefcnt, int arridx, int flags, char_u *word, slang_T *slang, int cond_req)); static void find_prefix __ARGS((matchinf_T *mip, int mode)); static int fold_more __ARGS((matchinf_T *mip)); @@ -1519,6 +1523,11 @@ ((unsigned)flags >> 24))) continue; + /* If there is a match with a CHECKCOMPOUNDPATTERN rule + * discard the compound word. */ + if (match_checkcompoundpattern(ptr, wlen, &slang->sl_comppat)) + continue; + if (mode == FIND_COMPOUND) { int capflags; @@ -1577,6 +1586,11 @@ if (!can_compound(slang, fword, mip->mi_compflags)) continue; } + else if (slang->sl_comprules != NULL + && !match_compoundrule(slang, mip->mi_compflags)) + /* The compound flags collected so far do not match any + * COMPOUNDRULE, discard the compounded word. */ + continue; } /* Check NEEDCOMPOUND: can't use word without compounding. */ @@ -1727,6 +1741,39 @@ } /* + * Return TRUE if there is a match between the word ptr[wlen] and + * CHECKCOMPOUNDPATTERN rules, assuming that we will concatenate with another + * word. + * A match means that the first part of CHECKCOMPOUNDPATTERN matches at the + * end of ptr[wlen] and the second part matches after it. + */ + static int +match_checkcompoundpattern(ptr, wlen, gap) + char_u *ptr; + int wlen; + garray_T *gap; /* &sl_comppat */ +{ + int i; + char_u *p; + int len; + + for (i = 0; i + 1 < gap->ga_len; i += 2) + { + p = ((char_u **)gap->ga_data)[i + 1]; + if (STRNCMP(ptr + wlen, p, STRLEN(p)) == 0) + { + /* Second part matches at start of following compound word, now + * check if first part matches at end of previous word. */ + p = ((char_u **)gap->ga_data)[i]; + len = (int)STRLEN(p); + if (len <= wlen && STRNCMP(ptr + wlen - len, p, len) == 0) + return TRUE; + } + } + return FALSE; +} + +/* * Return TRUE if "flags" is a valid sequence of compound flags and "word" * does not have too many syllables. */ @@ -1773,6 +1820,98 @@ } /* + * Return TRUE when the sequence of flags in "compflags" plus "flag" can + * possibly form a valid compounded word. This also checks the COMPOUNDRULE + * lines if they don't contain wildcards. + */ + static int +can_be_compound(sp, slang, compflags, flag) + trystate_T *sp; + slang_T *slang; + char_u *compflags; + int flag; +{ + /* If the flag doesn't appear in sl_compstartflags or sl_compallflags + * then it can't possibly compound. */ + if (!byte_in_str(sp->ts_complen == sp->ts_compsplit + ? slang->sl_compstartflags : slang->sl_compallflags, flag)) + return FALSE; + + /* If there are no wildcards, we can check if the flags collected so far + * possibly can form a match with COMPOUNDRULE patterns. This only + * makes sense when we have two or more words. */ + if (slang->sl_comprules != NULL && sp->ts_complen > sp->ts_compsplit) + { + int v; + + compflags[sp->ts_complen] = flag; + compflags[sp->ts_complen + 1] = NUL; + v = match_compoundrule(slang, compflags + sp->ts_compsplit); + compflags[sp->ts_complen] = NUL; + return v; + } + + return TRUE; +} + + +/* + * Return TRUE if the compound flags in compflags[] match the start of any + * compound rule. This is used to stop trying a compound if the flags + * collected so far can't possibly match any compound rule. + * Caller must check that slang->sl_comprules is not NULL. + */ + static int +match_compoundrule(slang, compflags) + slang_T *slang; + char_u *compflags; +{ + char_u *p; + int i; + int c; + + /* loop over all the COMPOUNDRULE entries */ + for (p = slang->sl_comprules; *p != NUL; ++p) + { + /* loop over the flags in the compound word we have made, match + * them against the current rule entry */ + for (i = 0; ; ++i) + { + c = compflags[i]; + if (c == NUL) + /* found a rule that matches for the flags we have so far */ + return TRUE; + if (*p == '/' || *p == NUL) + break; /* end of rule, it's too short */ + if (*p == '[') + { + int match = FALSE; + + /* compare against all the flags in [] */ + ++p; + while (*p != ']' && *p != NUL) + if (*p++ == c) + match = TRUE; + if (!match) + break; /* none matches */ + } + else if (*p != c) + break; /* flag of word doesn't match flag in pattern */ + ++p; + } + + /* Skip to the next "/", where the next pattern starts. */ + p = vim_strchr(p, '/'); + if (p == NULL) + break; + } + + /* Checked all the rules and none of them match the flags, so there + * can't possibly be a compound starting with these flags. */ + return FALSE; +} + +/* * Return non-zero if the prefix indicated by "arridx" matches with the prefix * ID in "flags" for the word "word". * The WF_RAREPFX flag is included in the return value for a rare prefix. @@ -2237,7 +2376,7 @@ /* If we are back at the starting line and there is no match then * give up. */ - if (lnum == wp->w_cursor.lnum && !found_one) + if (lnum == wp->w_cursor.lnum && (!found_one || wrapped)) break; /* Skip the characters at the start of the next line that were @@ -2513,9 +2652,11 @@ lp->sl_midword = NULL; vim_free(lp->sl_compprog); + vim_free(lp->sl_comprules); vim_free(lp->sl_compstartflags); vim_free(lp->sl_compallflags); lp->sl_compprog = NULL; + lp->sl_comprules = NULL; lp->sl_compstartflags = NULL; lp->sl_compallflags = NULL; @@ -3460,6 +3601,7 @@ char_u *pp; char_u *cp; char_u *ap; + char_u *crp; int cnt; garray_T *gap; @@ -3545,6 +3687,12 @@ slang->sl_compallflags = ap; *ap = NUL; + /* And a list of all patterns in their original form, for checking whether + * compounding may work in match_compoundrule(). This is freed when we + * encounter a wildcard, the check doesn't work then. */ + crp = alloc(todo + 1); + slang->sl_comprules = crp; + pp = pat; *pp++ = '^'; *pp++ = '\\'; @@ -3587,6 +3735,20 @@ atstart = 0; } } + + /* Copy flag to "sl_comprules", unless we run into a wildcard. */ + if (crp != NULL) + { + if (c == '+' || c == '*') + { + vim_free(slang->sl_comprules); + slang->sl_comprules = NULL; + crp = NULL; + } + else + *crp++ = c; + } + if (c == '/') /* slash separates two items */ { *pp++ = '\\'; @@ -3611,6 +3773,9 @@ *pp++ = '$'; *pp = NUL; + if (crp != NULL) + *crp = NUL; + slang->sl_compprog = vim_regcomp(pat, RE_MAGIC + RE_STRING + RE_STRICT); vim_free(pat); if (slang->sl_compprog == NULL) @@ -4791,13 +4956,16 @@ * Structure that is used to store the items in the word tree. This avoids * the need to keep track of each allocated thing, everything is freed all at * once after ":mkspell" is done. + * Note: "sb_next" must be just before "sb_data" to make sure the alignment of + * "sb_data" is correct for systems where pointers must be aligned on + * pointer-size boundaries and sizeof(pointer) > sizeof(int) (e.g., Sparc). */ #define SBLOCKSIZE 16000 /* size of sb_data */ typedef struct sblock_S sblock_T; struct sblock_S { - sblock_T *sb_next; /* next block in list */ int sb_used; /* nr of bytes already in use */ + sblock_T *sb_next; /* next block in list */ char_u sb_data[1]; /* data, actually longer */ }; @@ -4915,6 +5083,7 @@ } spellinfo_T; static afffile_T *spell_read_aff __ARGS((spellinfo_T *spin, char_u *fname)); +static int is_aff_rule __ARGS((char_u **items, int itemcnt, char *rulename, int mincount)); static void aff_process_flags __ARGS((afffile_T *affile, affentry_T *entry)); static int spell_info_item __ARGS((char_u *s)); static unsigned affitem2flag __ARGS((int flagtype, char_u *item, char_u *fname, int lnum)); @@ -4950,7 +5119,7 @@ static void put_sugtime __ARGS((spellinfo_T *spin, FILE *fd)); static int write_vim_spell __ARGS((spellinfo_T *spin, char_u *fname)); static void clear_node __ARGS((wordnode_T *node)); -static int put_node __ARGS((FILE *fd, wordnode_T *node, int index, int regionmask, int prefixtree)); +static int put_node __ARGS((FILE *fd, wordnode_T *node, int idx, int regionmask, int prefixtree)); static void spell_make_sugfile __ARGS((spellinfo_T *spin, char_u *wfname)); static int sug_filltree __ARGS((spellinfo_T *spin, slang_T *slang)); static int sug_maketable __ARGS((spellinfo_T *spin)); @@ -5223,8 +5392,7 @@ /* Handle non-empty lines. */ if (itemcnt > 0) { - if (STRCMP(items[0], "SET") == 0 && itemcnt == 2 - && aff->af_enc == NULL) + if (is_aff_rule(items, itemcnt, "SET", 2) && aff->af_enc == NULL) { #ifdef FEAT_MBYTE /* Setup for conversion from "ENC" to 'encoding'. */ @@ -5239,7 +5407,7 @@ smsg((char_u *)_("Conversion in %s not supported"), fname); #endif } - else if (STRCMP(items[0], "FLAG") == 0 && itemcnt == 2 + else if (is_aff_rule(items, itemcnt, "FLAG", 2) && aff->af_flagtype == AFT_CHAR) { if (STRCMP(items[1], "long") == 0) @@ -5284,69 +5452,71 @@ spin->si_info = p; } } - else if (STRCMP(items[0], "MIDWORD") == 0 && itemcnt == 2 + else if (is_aff_rule(items, itemcnt, "MIDWORD", 2) && midword == NULL) { midword = getroom_save(spin, items[1]); } - else if (STRCMP(items[0], "TRY") == 0 && itemcnt == 2) + else if (is_aff_rule(items, itemcnt, "TRY", 2)) { /* ignored, we look in the tree for what chars may appear */ } /* TODO: remove "RAR" later */ - else if ((STRCMP(items[0], "RAR") == 0 - || STRCMP(items[0], "RARE") == 0) && itemcnt == 2 - && aff->af_rare == 0) + else if ((is_aff_rule(items, itemcnt, "RAR", 2) + || is_aff_rule(items, itemcnt, "RARE", 2)) + && aff->af_rare == 0) { aff->af_rare = affitem2flag(aff->af_flagtype, items[1], fname, lnum); } /* TODO: remove "KEP" later */ - else if ((STRCMP(items[0], "KEP") == 0 - || STRCMP(items[0], "KEEPCASE") == 0) && itemcnt == 2 + else if ((is_aff_rule(items, itemcnt, "KEP", 2) + || is_aff_rule(items, itemcnt, "KEEPCASE", 2)) && aff->af_keepcase == 0) { aff->af_keepcase = affitem2flag(aff->af_flagtype, items[1], fname, lnum); } - else if (STRCMP(items[0], "BAD") == 0 && itemcnt == 2 - && aff->af_bad == 0) + else if ((is_aff_rule(items, itemcnt, "BAD", 2) + || is_aff_rule(items, itemcnt, "FORBIDDENWORD", 2)) + && aff->af_bad == 0) { aff->af_bad = affitem2flag(aff->af_flagtype, items[1], fname, lnum); } - else if (STRCMP(items[0], "NEEDAFFIX") == 0 && itemcnt == 2 + else if (is_aff_rule(items, itemcnt, "NEEDAFFIX", 2) && aff->af_needaffix == 0) { aff->af_needaffix = affitem2flag(aff->af_flagtype, items[1], fname, lnum); } - else if (STRCMP(items[0], "CIRCUMFIX") == 0 && itemcnt == 2 + else if (is_aff_rule(items, itemcnt, "CIRCUMFIX", 2) && aff->af_circumfix == 0) { aff->af_circumfix = affitem2flag(aff->af_flagtype, items[1], fname, lnum); } - else if (STRCMP(items[0], "NOSUGGEST") == 0 && itemcnt == 2 + else if (is_aff_rule(items, itemcnt, "NOSUGGEST", 2) && aff->af_nosuggest == 0) { aff->af_nosuggest = affitem2flag(aff->af_flagtype, items[1], fname, lnum); } - else if (STRCMP(items[0], "NEEDCOMPOUND") == 0 && itemcnt == 2 + else if ((is_aff_rule(items, itemcnt, "NEEDCOMPOUND", 2) + || is_aff_rule(items, itemcnt, "ONLYINCOMPOUND", 2)) && aff->af_needcomp == 0) { aff->af_needcomp = affitem2flag(aff->af_flagtype, items[1], fname, lnum); } - else if (STRCMP(items[0], "COMPOUNDROOT") == 0 && itemcnt == 2 + else if (is_aff_rule(items, itemcnt, "COMPOUNDROOT", 2) && aff->af_comproot == 0) { aff->af_comproot = affitem2flag(aff->af_flagtype, items[1], fname, lnum); } - else if (STRCMP(items[0], "COMPOUNDFORBIDFLAG") == 0 - && itemcnt == 2 && aff->af_compforbid == 0) + else if (is_aff_rule(items, itemcnt, "COMPOUNDFORBIDFLAG", 2) + && aff->af_compforbid == 0) { aff->af_compforbid = affitem2flag(aff->af_flagtype, items[1], fname, lnum); @@ -5354,8 +5524,8 @@ smsg((char_u *)_("Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line %d"), fname, lnum); } - else if (STRCMP(items[0], "COMPOUNDPERMITFLAG") == 0 - && itemcnt == 2 && aff->af_comppermit == 0) + else if (is_aff_rule(items, itemcnt, "COMPOUNDPERMITFLAG", 2) + && aff->af_comppermit == 0) { aff->af_comppermit = affitem2flag(aff->af_flagtype, items[1], fname, lnum); @@ -5363,7 +5533,7 @@ smsg((char_u *)_("Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line %d"), fname, lnum); } - else if (STRCMP(items[0], "COMPOUNDFLAG") == 0 && itemcnt == 2 + else if (is_aff_rule(items, itemcnt, "COMPOUNDFLAG", 2) && compflags == NULL) { /* Turn flag "c" into COMPOUNDRULE compatible string "c+", @@ -5376,7 +5546,15 @@ compflags = p; } } - else if (STRCMP(items[0], "COMPOUNDRULE") == 0 && itemcnt == 2) + else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2)) + { + /* We don't use the count, but do check that it's a number and + * not COMPOUNDRULE mistyped. */ + if (atoi((char *)items[1]) == 0) + smsg((char_u *)_("Wrong COMPOUNDRULES value in %s line %d: %s"), + fname, lnum, items[1]); + } + else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2)) { /* Concatenate this string to previously defined ones, using a * slash to separate them. */ @@ -5395,7 +5573,7 @@ compflags = p; } } - else if (STRCMP(items[0], "COMPOUNDWORDMAX") == 0 && itemcnt == 2 + else if (is_aff_rule(items, itemcnt, "COMPOUNDWORDMAX", 2) && compmax == 0) { compmax = atoi((char *)items[1]); @@ -5403,7 +5581,7 @@ smsg((char_u *)_("Wrong COMPOUNDWORDMAX value in %s line %d: %s"), fname, lnum, items[1]); } - else if (STRCMP(items[0], "COMPOUNDMIN") == 0 && itemcnt == 2 + else if (is_aff_rule(items, itemcnt, "COMPOUNDMIN", 2) && compminlen == 0) { compminlen = atoi((char *)items[1]); @@ -5411,7 +5589,7 @@ smsg((char_u *)_("Wrong COMPOUNDMIN value in %s line %d: %s"), fname, lnum, items[1]); } - else if (STRCMP(items[0], "COMPOUNDSYLMAX") == 0 && itemcnt == 2 + else if (is_aff_rule(items, itemcnt, "COMPOUNDSYLMAX", 2) && compsylmax == 0) { compsylmax = atoi((char *)items[1]); @@ -5419,32 +5597,29 @@ smsg((char_u *)_("Wrong COMPOUNDSYLMAX value in %s line %d: %s"), fname, lnum, items[1]); } - else if (STRCMP(items[0], "CHECKCOMPOUNDDUP") == 0 && itemcnt == 1) + else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDDUP", 1)) { compoptions |= COMP_CHECKDUP; } - else if (STRCMP(items[0], "CHECKCOMPOUNDREP") == 0 && itemcnt == 1) + else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDREP", 1)) { compoptions |= COMP_CHECKREP; } - else if (STRCMP(items[0], "CHECKCOMPOUNDCASE") == 0 && itemcnt == 1) + else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDCASE", 1)) { compoptions |= COMP_CHECKCASE; } - else if (STRCMP(items[0], "CHECKCOMPOUNDTRIPLE") == 0 - && itemcnt == 1) + else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDTRIPLE", 1)) { compoptions |= COMP_CHECKTRIPLE; } - else if (STRCMP(items[0], "CHECKCOMPOUNDPATTERN") == 0 - && itemcnt == 2) + else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 2)) { if (atoi((char *)items[1]) == 0) smsg((char_u *)_("Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"), fname, lnum, items[1]); } - else if (STRCMP(items[0], "CHECKCOMPOUNDPATTERN") == 0 - && itemcnt == 3) + else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 3)) { garray_T *gap = &spin->si_comppat; int i; @@ -5463,24 +5638,24 @@ = getroom_save(spin, items[2]); } } - else if (STRCMP(items[0], "SYLLABLE") == 0 && itemcnt == 2 + else if (is_aff_rule(items, itemcnt, "SYLLABLE", 2) && syllable == NULL) { syllable = getroom_save(spin, items[1]); } - else if (STRCMP(items[0], "NOBREAK") == 0 && itemcnt == 1) + else if (is_aff_rule(items, itemcnt, "NOBREAK", 1)) { spin->si_nobreak = TRUE; } - else if (STRCMP(items[0], "NOSPLITSUGS") == 0 && itemcnt == 1) + else if (is_aff_rule(items, itemcnt, "NOSPLITSUGS", 1)) { spin->si_nosplitsugs = TRUE; } - else if (STRCMP(items[0], "NOSUGFILE") == 0 && itemcnt == 1) + else if (is_aff_rule(items, itemcnt, "NOSUGFILE", 1)) { spin->si_nosugfile = TRUE; } - else if (STRCMP(items[0], "PFXPOSTPONE") == 0 && itemcnt == 1) + else if (is_aff_rule(items, itemcnt, "PFXPOSTPONE", 1)) { aff->af_pfxpostpone = TRUE; } @@ -5771,24 +5946,20 @@ } } } - else if (STRCMP(items[0], "FOL") == 0 && itemcnt == 2 - && fol == NULL) + else if (is_aff_rule(items, itemcnt, "FOL", 2) && fol == NULL) { fol = vim_strsave(items[1]); } - else if (STRCMP(items[0], "LOW") == 0 && itemcnt == 2 - && low == NULL) + else if (is_aff_rule(items, itemcnt, "LOW", 2) && low == NULL) { low = vim_strsave(items[1]); } - else if (STRCMP(items[0], "UPP") == 0 && itemcnt == 2 - && upp == NULL) + else if (is_aff_rule(items, itemcnt, "UPP", 2) && upp == NULL) { upp = vim_strsave(items[1]); } - else if ((STRCMP(items[0], "REP") == 0 - || STRCMP(items[0], "REPSAL") == 0) - && itemcnt == 2) + else if (is_aff_rule(items, itemcnt, "REP", 2) + || is_aff_rule(items, itemcnt, "REPSAL", 2)) { /* Ignore REP/REPSAL count */; if (!isdigit(*items[1])) @@ -5819,7 +5990,7 @@ : &spin->si_rep, items[1], items[2]); } } - else if (STRCMP(items[0], "MAP") == 0 && itemcnt == 2) + else if (is_aff_rule(items, itemcnt, "MAP", 2)) { /* MAP item or count */ if (!found_map) @@ -5856,9 +6027,8 @@ ga_append(&spin->si_map, '/'); } } - /* Accept "SAL from to" and "SAL from to # comment". */ - else if (STRCMP(items[0], "SAL") == 0 - && (itemcnt == 3 || (itemcnt > 3 && items[3][0] == '#'))) + /* Accept "SAL from to" and "SAL from to #comment". */ + else if (is_aff_rule(items, itemcnt, "SAL", 3)) { if (do_sal) { @@ -5877,12 +6047,12 @@ : items[2]); } } - else if (STRCMP(items[0], "SOFOFROM") == 0 && itemcnt == 2 + else if (is_aff_rule(items, itemcnt, "SOFOFROM", 2) && sofofrom == NULL) { sofofrom = getroom_save(spin, items[1]); } - else if (STRCMP(items[0], "SOFOTO") == 0 && itemcnt == 2 + else if (is_aff_rule(items, itemcnt, "SOFOTO", 2) && sofoto == NULL) { sofoto = getroom_save(spin, items[1]); @@ -5980,7 +6150,7 @@ else if (spin->si_newprefID == 0 || spin->si_newprefID == 127) MSG(_("Too many compound flags")); else - MSG(_("Too many posponed prefixes and/or compound flags")); + MSG(_("Too many postponed prefixes and/or compound flags")); } if (syllable != NULL) @@ -6017,6 +6187,22 @@ } /* + * Return TRUE when items[0] equals "rulename", there are "mincount" items or + * a comment is following after item "mincount". + */ + static int +is_aff_rule(items, itemcnt, rulename, mincount) + char_u **items; + int itemcnt; + char *rulename; + int mincount; +{ + return (STRCMP(items[0], rulename) == 0 + && (itemcnt == mincount + || (itemcnt > mincount && items[mincount][0] == '#'))); +} + +/* * For affix "entry" move COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG from * ae_flags to ae_comppermit and ae_compforbid. */ @@ -7926,6 +8112,8 @@ char_u *p; int rr; int retval = OK; + size_t fwv = 1; /* collect return value of fwrite() to avoid + warnings from picky compiler */ fd = mch_fopen((char *)fname, "w"); if (fd == NULL) @@ -7936,11 +8124,11 @@ /*
: */ /* */ - if (fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, (size_t)1, fd) != 1) - { - EMSG(_(e_write)); - retval = FAIL; - } + fwv &= fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, (size_t)1, fd); + if (fwv != (size_t)1) + /* Catch first write error, don't try writing more. */ + goto theend; + putc(VIMSPELLVERSION, fd); /* */ /* @@ -7955,7 +8143,7 @@ i = (int)STRLEN(spin->si_info); put_bytes(fd, (long_u)i, 4); /* */ - fwrite(spin->si_info, (size_t)i, (size_t)1, fd); /* */ + fwv &= fwrite(spin->si_info, (size_t)i, (size_t)1, fd); /* */ } /* SN_REGION: ... @@ -7966,7 +8154,7 @@ putc(SNF_REQUIRED, fd); /* */ l = spin->si_region_count * 2; put_bytes(fd, (long_u)l, 4); /* */ - fwrite(spin->si_region_name, (size_t)l, (size_t)1, fd); + fwv &= fwrite(spin->si_region_name, (size_t)l, (size_t)1, fd); /* ... */ regionmask = (1 << spin->si_region_count) - 1; } @@ -8016,7 +8204,7 @@ } put_bytes(fd, (long_u)l, 2); /* */ - fwrite(folchars, (size_t)l, (size_t)1, fd); /* */ + fwv &= fwrite(folchars, (size_t)l, (size_t)1, fd); /* */ } /* SN_MIDWORD: */ @@ -8027,7 +8215,8 @@ i = (int)STRLEN(spin->si_midword); put_bytes(fd, (long_u)i, 4); /* */ - fwrite(spin->si_midword, (size_t)i, (size_t)1, fd); /* */ + fwv &= fwrite(spin->si_midword, (size_t)i, (size_t)1, fd); + /* */ } /* SN_PREFCOND: ... */ @@ -8113,7 +8302,8 @@ p = rr == 1 ? ftp->ft_from : ftp->ft_to; l = (int)STRLEN(p); putc(l, fd); - fwrite(p, l, (size_t)1, fd); + if (l > 0) + fwv &= fwrite(p, l, (size_t)1, fd); } } @@ -8131,11 +8321,11 @@ /* */ put_bytes(fd, (long_u)l, 2); /* */ - fwrite(spin->si_sofofr, l, (size_t)1, fd); /* */ + fwv &= fwrite(spin->si_sofofr, l, (size_t)1, fd); /* */ l = (int)STRLEN(spin->si_sofoto); put_bytes(fd, (long_u)l, 2); /* */ - fwrite(spin->si_sofoto, l, (size_t)1, fd); /* */ + fwv &= fwrite(spin->si_sofoto, l, (size_t)1, fd); /* */ } /* SN_WORDS: ... @@ -8160,7 +8350,7 @@ l = (int)STRLEN(hi->hi_key) + 1; len += l; if (round == 2) /* */ - fwrite(hi->hi_key, (size_t)l, (size_t)1, fd); + fwv &= fwrite(hi->hi_key, (size_t)l, (size_t)1, fd); --todo; } if (round == 1) @@ -8176,7 +8366,7 @@ putc(0, fd); /* */ l = spin->si_map.ga_len; put_bytes(fd, (long_u)l, 4); /* */ - fwrite(spin->si_map.ga_data, (size_t)l, (size_t)1, fd); + fwv &= fwrite(spin->si_map.ga_data, (size_t)l, (size_t)1, fd); /* */ } @@ -8232,10 +8422,11 @@ { p = ((char_u **)(spin->si_comppat.ga_data))[i]; putc((int)STRLEN(p), fd); /* */ - fwrite(p, (size_t)STRLEN(p), (size_t)1, fd);/* */ + fwv &= fwrite(p, (size_t)STRLEN(p), (size_t)1, fd); + /* */ } /* */ - fwrite(spin->si_compflags, (size_t)STRLEN(spin->si_compflags), + fwv &= fwrite(spin->si_compflags, (size_t)STRLEN(spin->si_compflags), (size_t)1, fd); } @@ -8259,7 +8450,8 @@ l = (int)STRLEN(spin->si_syllable); put_bytes(fd, (long_u)l, 4); /* */ - fwrite(spin->si_syllable, (size_t)l, (size_t)1, fd); /* */ + fwv &= fwrite(spin->si_syllable, (size_t)l, (size_t)1, fd); + /* */ } /* end of */ @@ -8295,13 +8487,18 @@ (void)put_node(fd, tree, 0, regionmask, round == 3); } - /* Write another byte to check for errors. */ + /* Write another byte to check for errors (file system full). */ if (putc(0, fd) == EOF) retval = FAIL; - +theend: if (fclose(fd) == EOF) retval = FAIL; + if (fwv != (size_t)1) + retval = FAIL; + if (retval == FAIL) + EMSG(_(e_write)); + return retval; } @@ -9890,6 +10087,7 @@ char_u *p; int len; int totlen; + size_t x = 1; /* collect return value of fwrite() */ if (fd != NULL) put_bytes(fd, (long_u)gap->ga_len, 2); /* */ @@ -9906,7 +10104,7 @@ if (fd != NULL) { fputc(len, fd); - fwrite(p, (size_t)len, (size_t)1, fd); + x &= fwrite(p, (size_t)len, (size_t)1, fd); } totlen += len; } @@ -11480,15 +11678,24 @@ vim_strncpy(preword + sp->ts_prewordlen, tword + sp->ts_splitoff, sp->ts_twordlen - sp->ts_splitoff); - p = preword; - while (*skiptowhite(p) != NUL) - p = skipwhite(skiptowhite(p)); - if (fword_ends && !can_compound(slang, p, - compflags + sp->ts_compsplit)) - /* Compound is not allowed. But it may still be - * possible if we add another (short) word. */ + + /* Verify CHECKCOMPOUNDPATTERN rules. */ + if (match_checkcompoundpattern(preword, sp->ts_prewordlen, + &slang->sl_comppat)) compound_ok = FALSE; + if (compound_ok) + { + p = preword; + while (*skiptowhite(p) != NUL) + p = skipwhite(skiptowhite(p)); + if (fword_ends && !can_compound(slang, p, + compflags + sp->ts_compsplit)) + /* Compound is not allowed. But it may still be + * possible if we add another (short) word. */ + compound_ok = FALSE; + } + /* Get pointer to last char of previous word. */ p = preword + sp->ts_prewordlen; mb_ptr_back(preword, p); @@ -11685,10 +11892,9 @@ && (slang->sl_compsylmax < MAXWLEN || sp->ts_complen + 1 - sp->ts_compsplit < slang->sl_compmax) - && (byte_in_str(sp->ts_complen == sp->ts_compsplit - ? slang->sl_compstartflags - : slang->sl_compallflags, - ((unsigned)flags >> 24)))) + && (can_be_compound(sp, slang, + compflags, ((unsigned)flags >> 24)))) + { try_compound = TRUE; compflags[sp->ts_complen] = ((unsigned)flags >> 24); @@ -14808,7 +15014,7 @@ case 0: /* - * Lenghts are equal, thus changes must result in same length: An + * Lengths are equal, thus changes must result in same length: An * insert is only possible in combination with a delete. * 1: check if for identical strings */ diff -Naur vim72.orig/src/structs.h vim72/src/structs.h --- vim72.orig/src/structs.h 2008-07-30 13:02:50.000000000 -0700 +++ vim72/src/structs.h 2009-03-22 21:28:40.380513201 -0700 @@ -459,7 +459,7 @@ typedef struct { int hide; /* TRUE when ":hide" was used */ -# ifdef FEAT_BROWSE +# ifdef FEAT_BROWSE_CMD int browse; /* TRUE to invoke file dialog */ # endif # ifdef FEAT_WINDOWS @@ -1784,10 +1784,15 @@ #endif /* - * The next three specify the offsets for displaying the buffer: + * "w_topline", "w_leftcol" and "w_skipcol" specify the offsets for + * displaying the buffer. */ linenr_T w_topline; /* buffer line number of the line at the top of the window */ +#ifdef FEAT_AUTOCMD + char w_topline_was_set; /* flag set to TRUE when topline is set, + e.g. by winrestview() */ +#endif #ifdef FEAT_DIFF int w_topfill; /* number of filler lines above w_topline */ int w_old_topfill; /* w_topfill at last redraw */ diff -Naur vim72.orig/src/tag.c vim72/src/tag.c --- vim72.orig/src/tag.c 2008-07-16 14:31:30.000000000 -0700 +++ vim72/src/tag.c 2009-03-22 21:32:03.853549379 -0700 @@ -515,7 +515,7 @@ * If a count is supplied to the ":tag " command, then * jump to count'th matching tag. */ - if (type == DT_TAG && count > 0) + if (type == DT_TAG && *tag != NUL && count > 0) cur_match = count - 1; if (type == DT_SELECT || type == DT_JUMP @@ -618,7 +618,7 @@ taglen_advance(taglen); MSG_PUTS_ATTR(_("file\n"), hl_attr(HLF_T)); - for (i = 0; i < num_matches; ++i) + for (i = 0; i < num_matches && !got_int; ++i) { parse_match(matches[i], &tagp); if (!new_tag && ( @@ -655,6 +655,8 @@ } if (msg_col > 0) msg_putchar('\n'); + if (got_int) + break; msg_advance(15); /* print any extra fields */ @@ -689,6 +691,8 @@ if (msg_col + ptr2cells(p) >= Columns) { msg_putchar('\n'); + if (got_int) + break; msg_advance(15); } p = msg_outtrans_one(p, attr); @@ -704,6 +708,8 @@ if (msg_col > 15) { msg_putchar('\n'); + if (got_int) + break; msg_advance(15); } } @@ -734,6 +740,8 @@ { if (msg_col + (*p == TAB ? 1 : ptr2cells(p)) > Columns) msg_putchar('\n'); + if (got_int) + break; msg_advance(15); /* skip backslash used for escaping command char */ @@ -760,12 +768,9 @@ if (msg_col) msg_putchar('\n'); ui_breakcheck(); - if (got_int) - { - got_int = FALSE; /* only stop the listing */ - break; - } } + if (got_int) + got_int = FALSE; /* only stop the listing */ ask_for_selection = TRUE; } #if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL) @@ -2542,6 +2547,15 @@ { ga_clear_strings(&tag_fnames); do_tag(NULL, DT_FREE, 0, 0, 0); + tag_freematch(); + +# if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX) + if (ptag_entry.tagname) + { + vim_free(ptag_entry.tagname); + ptag_entry.tagname = NULL; + } +# endif } #endif @@ -2725,7 +2739,24 @@ */ p_7f = vim_strchr(lbuf, 0x7f); if (p_7f == NULL) + { +etag_fail: + if (vim_strchr(lbuf, '\n') == NULL) + { + /* Truncated line. Ignore it. */ + if (p_verbose >= 5) + { + verbose_enter(); + MSG(_("Ignoring long line in tags file")); + verbose_leave(); + } + tagp->command = lbuf; + tagp->tagname = lbuf; + tagp->tagname_end = lbuf; + return OK; + } return FAIL; + } /* Find ^A. If not found the line number is after the 0x7f */ p = vim_strchr(p_7f, Ctrl_A); @@ -2735,7 +2766,7 @@ ++p; if (!VIM_ISDIGIT(*p)) /* check for start of line number */ - return FAIL; + goto etag_fail; tagp->command = p; @@ -2749,7 +2780,7 @@ /* find end of tagname */ for (p = p_7f - 1; !vim_iswordc(*p); --p) if (p == lbuf) - return FAIL; + goto etag_fail; tagp->tagname_end = p + 1; while (p >= lbuf && vim_iswordc(*p)) --p; diff -Naur vim72.orig/src/term.c vim72/src/term.c --- vim72.orig/src/term.c 2008-07-27 04:48:06.000000000 -0700 +++ vim72/src/term.c 2009-03-22 21:30:28.311427015 -0700 @@ -4920,7 +4920,15 @@ key_name[0] = KEY2TERMCAP0(key); key_name[1] = KEY2TERMCAP1(key); if (key_name[0] == KS_KEY) - string[new_slen++] = key_name[1]; /* from ":set =xx" */ + { + /* from ":set =xx" */ +#ifdef FEAT_MBYTE + if (has_mbyte) + new_slen += (*mb_char2bytes)(key_name[1], string + new_slen); + else +#endif + string[new_slen++] = key_name[1]; + } else { string[new_slen++] = K_SPECIAL; diff -Naur vim72.orig/src/testdir/Makefile vim72/src/testdir/Makefile --- vim72.orig/src/testdir/Makefile 2008-06-19 13:29:46.000000000 -0700 +++ vim72/src/testdir/Makefile 2009-03-22 21:32:36.451638218 -0700 @@ -20,21 +20,23 @@ test48.out test49.out test51.out test52.out test53.out \ test54.out test55.out test56.out test57.out test58.out \ test59.out test60.out test61.out test62.out test63.out \ - test64.out test65.out + test64.out test65.out test66.out SCRIPTS_GUI = test16.out .SUFFIXES: .in .out -nongui: nolog $(SCRIPTS) - @echo - @cat test.log - @echo ALL DONE +nongui: nolog $(SCRIPTS) report + +gui: nolog $(SCRIPTS) $(SCRIPTS_GUI) report -gui: nolog $(SCRIPTS) $(SCRIPTS_GUI) +report: @echo - @cat test.log - @echo ALL DONE + @echo 'Test results:' + @/bin/sh -c "if test -f test.log; \ + then cat test.log; echo TEST FAILURE; exit 1; \ + else echo ALL DONE; \ + fi" $(SCRIPTS) $(SCRIPTS_GUI): $(VIMPROG) @@ -71,4 +73,4 @@ test60.out: test60.vim nolog: - -echo Test results: >test.log + -rm -f test.log diff -Naur vim72.orig/src/testdir/Make_ming.mak vim72/src/testdir/Make_ming.mak --- vim72.orig/src/testdir/Make_ming.mak 1969-12-31 16:00:00.000000000 -0800 +++ vim72/src/testdir/Make_ming.mak 2009-03-22 21:27:50.249298785 -0700 @@ -0,0 +1,91 @@ +# Makefile to run tests for Vim, on Dos-like machines +# with sh.exe or zsh.exe in the path or not. +# +# Author: Bill McCarthy +# +# Note that test54 has been removed until it is fixed. +# +# Requires a set of Unix tools: echo, diff, etc. + +ifneq (sh.exe, $(SHELL)) +DEL = rm -f +MV = mv +CP = cp +DIRSLASH = / +else +DEL = del +MV = rename +CP = copy +DIRSLASH = \\ +endif + +VIMPROG = ..$(DIRSLASH)vim + +# Omitted: +# test2 "\\tmp" doesn't work. +# test10 'errorformat' is different +# test12 can't unlink a swap file +# test25 uses symbolic link +# test27 can't edit file with "*" in file name +# test31 16 bit version runs out of memory... + +SCRIPTS16 = test1.out test19.out test20.out test22.out \ + test23.out test24.out test28.out test29.out \ + test35.out test36.out test43.out \ + test44.out test45.out test46.out test47.out \ + test48.out test51.out test53.out \ + test55.out test56.out test57.out test58.out test59.out \ + test60.out test61.out test62.out test63.out test64.out + +# Had to remove test54 which doesn't work yet. +# test54.out + +SCRIPTS = test3.out test4.out test5.out test6.out test7.out \ + test8.out test9.out test11.out test13.out test14.out \ + test15.out test17.out test18.out test21.out test26.out \ + test30.out test31.out test32.out test33.out test34.out \ + test37.out test38.out test39.out test40.out test41.out \ + test42.out test52.out test65.out + +SCRIPTS32 = test50.out + +SCRIPTS_GUI = test16.out + +.SUFFIXES: .in .out + +vimall: fixff $(SCRIPTS16) $(SCRIPTS) $(SCRIPTS_GUI) $(SCRIPTS32) + echo ALL DONE + +nongui: fixff $(SCRIPTS16) $(SCRIPTS) + echo ALL DONE + +small: + echo ALL DONE + +gui: fixff $(SCRIPTS16) $(SCRIPTS) $(SCRIPTS_GUI) + echo ALL DONE + +win32: fixff $(SCRIPTS16) $(SCRIPTS) $(SCRIPTS32) + echo ALL DONE + +fixff: + -$(VIMPROG) -u dos.vim --noplugin "+argdo set ff=dos|upd" +q *.in *.ok + +clean: + -$(DEL) *.out + -$(DEL) test.ok + -$(DEL) small.vim + -$(DEL) tiny.vim + -$(DEL) mbyte.vim + -$(DEL) X* + -$(DEL) viminfo + +.in.out: + $(CP) $*.ok test.ok + $(VIMPROG) -u dos.vim -U NONE --noplugin -s dotest.in $*.in + diff test.out $*.ok + -$(DEL) $*.out + $(MV) test.out $*.out + -$(DEL) X* + -$(DEL) test.ok + -$(DEL) viminfo diff -Naur vim72.orig/src/testdir/test42.ok vim72/src/testdir/test42.ok --- vim72.orig/src/testdir/test42.ok 2008-02-20 04:27:37.000000000 -0800 +++ vim72/src/testdir/test42.ok 2009-03-22 21:28:17.791064674 -0700 @@ -20,7 +20,7 @@ ucs-2 - fileencoding=ucs-2le + fileencoding=utf-16le bomb ucs-2le diff -Naur vim72.orig/src/testdir/test66.in vim72/src/testdir/test66.in --- vim72.orig/src/testdir/test66.in 1969-12-31 16:00:00.000000000 -0800 +++ vim72/src/testdir/test66.in 2009-03-22 21:32:36.451638218 -0700 @@ -0,0 +1,25 @@ + +Test for visual block shift and tab characters. + +STARTTEST +:so small.vim +/^abcdefgh +4jI j<<11|D +7|a  +7|a  +7|a 4k13|4j< +:$-4,$w! test.out +:$-4,$s/\s\+//g +4kI j<< +7|a  +7|a  +7|a 4k13|4j3< +:$-4,$w >> test.out +:qa! +ENDTEST + +abcdefghijklmnopqrstuvwxyz +abcdefghijklmnopqrstuvwxyz +abcdefghijklmnopqrstuvwxyz +abcdefghijklmnopqrstuvwxyz +abcdefghijklmnopqrstuvwxyz diff -Naur vim72.orig/src/testdir/test66.ok vim72/src/testdir/test66.ok --- vim72.orig/src/testdir/test66.ok 1969-12-31 16:00:00.000000000 -0800 +++ vim72/src/testdir/test66.ok 2009-03-22 21:32:36.451638218 -0700 @@ -0,0 +1,10 @@ + abcdefghijklmnopqrstuvwxyz +abcdefghij + abc defghijklmnopqrstuvwxyz + abc defghijklmnopqrstuvwxyz + abc defghijklmnopqrstuvwxyz + abcdefghijklmnopqrstuvwxyz +abcdefghij + abc defghijklmnopqrstuvwxyz + abc defghijklmnopqrstuvwxyz + abc defghijklmnopqrstuvwxyz diff -Naur vim72.orig/src/ui.c vim72/src/ui.c --- vim72.orig/src/ui.c 2008-07-14 11:14:56.000000000 -0700 +++ vim72/src/ui.c 2009-03-22 21:29:14.058671044 -0700 @@ -1820,7 +1820,7 @@ #ifdef HAVE_DUP /* Use stderr for stdin, also works for shell commands. */ close(0); - dup(2); + ignored = dup(2); #else read_cmd_fd = 2; /* read from stderr instead of stdin */ #endif @@ -2020,7 +2020,7 @@ if (value == NULL || *length == 0) { - clip_free_selection(cbd); /* ??? [what's the query?] */ + clip_free_selection(cbd); /* nothing received, clear register */ *(int *)success = FALSE; return; } @@ -2076,7 +2076,7 @@ text_prop.value = (unsigned char *)value; text_prop.encoding = *type; text_prop.format = *format; - text_prop.nitems = STRLEN(value); + text_prop.nitems = len; status = XmbTextPropertyToTextList(X_DISPLAY, &text_prop, &text_list, &n_text); if (status != Success || n_text < 1) @@ -2110,6 +2110,8 @@ int i; int nbytes = 0; char_u *buffer; + time_t start_time; + int timed_out = FALSE; for (i = #ifdef FEAT_MBYTE @@ -2129,6 +2131,7 @@ case 3: type = text_atom; break; default: type = XA_STRING; } + success = MAYBE; XtGetSelectionValue(myShell, cbd->sel_atom, type, clip_x11_request_selection_cb, (XtPointer)&success, CurrentTime); @@ -2141,27 +2144,48 @@ * characters, then they will appear before the one that requested the * paste! Don't worry, we will catch up with any other events later. */ - for (;;) + start_time = time(NULL); + while (success == MAYBE) { - if (XCheckTypedEvent(dpy, SelectionNotify, &event)) - break; - if (XCheckTypedEvent(dpy, SelectionRequest, &event)) - /* We may get a SelectionRequest here and if we don't handle - * it we hang. KDE klipper does this, for example. */ + if (XCheckTypedEvent(dpy, SelectionNotify, &event) + || XCheckTypedEvent(dpy, SelectionRequest, &event) + || XCheckTypedEvent(dpy, PropertyNotify, &event)) + { + /* This is where clip_x11_request_selection_cb() should be + * called. It may actually happen a bit later, so we loop + * until "success" changes. + * We may get a SelectionRequest here and if we don't handle + * it we hang. KDE klipper does this, for example. + * We need to handle a PropertyNotify for large selections. */ XtDispatchEvent(&event); + continue; + } + + /* Time out after 2 to 3 seconds to avoid that we hang when the + * other process doesn't respond. Note that the SelectionNotify + * event may still come later when the selection owner comes back + * to life and the text gets inserted unexpectedly. Don't know + * why that happens or how to avoid that :-(. */ + if (time(NULL) > start_time + 2) + { + timed_out = TRUE; + break; + } /* Do we need this? Probably not. */ XSync(dpy, False); - /* Bernhard Walle solved a slow paste response in an X terminal by - * adding: usleep(10000); here. */ + /* Wait for 1 msec to avoid that we eat up all CPU time. */ + ui_delay(1L, TRUE); } - /* this is where clip_x11_request_selection_cb() is actually called */ - XtDispatchEvent(&event); - - if (success) + if (success == TRUE) return; + + /* don't do a retry with another type after timing out, otherwise we + * hang for 15 seconds. */ + if (timed_out) + break; } /* Final fallback position - use the X CUT_BUFFER0 store */ diff -Naur vim72.orig/src/version.c vim72/src/version.c --- vim72.orig/src/version.c 2008-08-09 07:24:52.000000000 -0700 +++ vim72/src/version.c 2009-03-22 21:33:03.705385948 -0700 @@ -677,9 +677,294 @@ static int included_patches[] = { /* Add new patch number below this line */ /**/ + 148, +/**/ + 147, +/**/ + 146, +/**/ + 145, +/**/ + 144, +/**/ + 143, +/**/ + 142, +/**/ + 141, +/**/ + 140, +/**/ + 139, +/**/ + 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, +/**/ + 100, +/**/ + 99, +/**/ + 98, +/**/ + 97, +/**/ + 96, +/**/ + 95, +/**/ + 94, +/**/ + 92, +/**/ + 91, +/**/ + 90, +/**/ + 87, +/**/ + 86, +/**/ + 85, +/**/ + 84, +/**/ + 83, +/**/ + 82, +/**/ + 81, +/**/ + 80, +/**/ + 79, +/**/ + 78, +/**/ + 77, +/**/ + 76, +/**/ + 75, +/**/ + 73, +/**/ + 70, +/**/ + 69, +/**/ + 68, +/**/ + 67, +/**/ + 66, +/**/ + 65, +/**/ + 64, +/**/ + 63, +/**/ + 62, +/**/ + 61, +/**/ + 60, +/**/ + 59, +/**/ + 58, +/**/ + 57, +/**/ + 56, +/**/ + 55, +/**/ + 54, +/**/ + 53, +/**/ + 52, +/**/ + 51, +/**/ + 50, +/**/ + 48, +/**/ + 47, +/**/ + 46, +/**/ + 45, +/**/ + 44, +/**/ + 43, +/**/ + 42, +/**/ + 40, +/**/ + 39, +/**/ + 38, +/**/ + 37, +/**/ + 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, +/**/ + 6, +/**/ + 5, +/**/ + 4, +/**/ + 3, +/**/ + 2, +/**/ + 1, +/**/ 0 }; +/* + * Place to put a short description when adding a feature with a patch. + * Keep it short, e.g.,: "relative numbers", "persistent undo". + * Also add a comment marker to separate the lines. + * See the official Vim patches for the diff format: It must use a context of + * one line only. Create it by hand or use "diff -C2" and edit the patch. + */ +static char *(extra_patches[]) = +{ /* Add your patch description below this line */ +/**/ + NULL +}; + int highest_patch() { @@ -786,7 +1071,7 @@ MSG_PUTS(_("\nRISC OS version")); #endif #ifdef VMS - MSG_PUTS("\nOpenVMS version"); + MSG_PUTS(_("\nOpenVMS version")); # ifdef HAVE_PATHDEF if (*compiled_arch != NUL) { @@ -825,6 +1110,19 @@ } } + /* Print the list of extra patch descriptions if there is at least one. */ + if (extra_patches[0] != NULL) + { + MSG_PUTS(_("\nExtra patches: ")); + s = ""; + for (i = 0; extra_patches[i] != NULL; ++i) + { + MSG_PUTS(s); + s = ", "; + MSG_PUTS(extra_patches[i]); + } + } + #ifdef MODIFIED_BY MSG_PUTS("\n"); MSG_PUTS(_("Modified by ")); diff -Naur vim72.orig/src/vim.h vim72/src/vim.h --- vim72.orig/src/vim.h 2008-08-09 09:03:38.000000000 -0700 +++ vim72/src/vim.h 2009-03-22 21:32:51.512605113 -0700 @@ -341,8 +341,14 @@ #ifdef BACKSLASH_IN_FILENAME # define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`%#'\"|!<") #else -# define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<") -# define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&") +# ifdef VMS + /* VMS allows a lot of characters in the file name */ +# define PATH_ESC_CHARS ((char_u *)" \t\n*?{`\\%#'\"|!") +# define SHELL_ESC_CHARS ((char_u *)" \t\n*?{`\\%#'|!()&") +# else +# define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<") +# define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&") +# endif #endif #define NUMBUFLEN 30 /* length of a buffer to store a number in ASCII */ @@ -370,7 +376,7 @@ * Define __w64 as an empty token for everything but MSVC 7.x or later. */ # if !defined(_MSC_VER) || (_MSC_VER < 1300) -# define __w64 +# define __w64 # endif typedef unsigned long __w64 long_u; typedef long __w64 long_i; @@ -702,6 +708,7 @@ #define EXPAND_USER_DEFINED 30 #define EXPAND_USER_LIST 31 #define EXPAND_SHELLCMD 32 +#define EXPAND_CSCOPE 33 /* Values for exmode_active (0 is no exmode) */ #define EXMODE_NORMAL 1 @@ -1051,6 +1058,7 @@ #define WSP_HELP 16 /* creating the help window */ #define WSP_BELOW 32 /* put new window below/right */ #define WSP_ABOVE 64 /* put new window above/left */ +#define WSP_NEWLOC 128 /* don't copy location list */ /* * arguments for gui_set_shellsize() @@ -1728,7 +1736,8 @@ #define VV_MOUSE_COL 51 #define VV_OP 52 #define VV_SEARCHFORWARD 53 -#define VV_LEN 54 /* number of v: vars */ +#define VV_OLDFILES 54 +#define VV_LEN 55 /* number of v: vars */ #ifdef FEAT_CLIPBOARD @@ -1979,6 +1988,9 @@ # endif #endif +#ifndef FEAT_NETBEANS_INTG +# undef NBDEBUG +#endif #ifdef NBDEBUG /* Netbeans debugging. */ # include "nbdebug.h" #else @@ -2054,4 +2066,10 @@ #define DOSO_VIMRC 1 /* loading vimrc file */ #define DOSO_GVIMRC 2 /* loading gvimrc file */ +/* flags for read_viminfo() and children */ +#define VIF_WANT_INFO 1 /* load non-mark info */ +#define VIF_WANT_MARKS 2 /* load file marks */ +#define VIF_FORCEIT 4 /* overwrite info already read */ +#define VIF_GET_OLDFILES 8 /* load v:oldfiles */ + #endif /* VIM__H */ diff -Naur vim72.orig/src/window.c vim72/src/window.c --- vim72.orig/src/window.c 2008-08-06 04:00:30.000000000 -0700 +++ vim72/src/window.c 2009-03-22 21:31:54.132928342 -0700 @@ -12,7 +12,7 @@ static int path_is_url __ARGS((char_u *p)); #if defined(FEAT_WINDOWS) || defined(PROTO) static int win_split_ins __ARGS((int size, int flags, win_T *newwin, int dir)); -static void win_init __ARGS((win_T *newp, win_T *oldp)); +static void win_init __ARGS((win_T *newp, win_T *oldp, int flags)); static void frame_comp_pos __ARGS((frame_T *topfrp, int *row, int *col)); static void frame_setheight __ARGS((frame_T *curfrp, int height)); #ifdef FEAT_VERTSPLIT @@ -593,9 +593,7 @@ ++allow_keys; /* no mapping for xchar, but allow key codes */ if (xchar == NUL) xchar = plain_vgetc(); -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(xchar, TRUE); -#endif --no_mapping; --allow_keys; #ifdef FEAT_CMDL_INFO @@ -912,7 +910,7 @@ return FAIL; /* make the contents of the new window the same as the current one */ - win_init(wp, curwin); + win_init(wp, curwin, flags); } /* @@ -1161,11 +1159,15 @@ * Initialize window "newp" from window "oldp". * Used when splitting a window and when creating a new tab page. * The windows will both edit the same buffer. + * WSP_NEWLOC may be specified in flags to prevent the location list from + * being copied. */ +/*ARGSUSED*/ static void -win_init(newp, oldp) +win_init(newp, oldp, flags) win_T *newp; win_T *oldp; + int flags; { int i; @@ -1190,7 +1192,14 @@ copy_jumplist(oldp, newp); #endif #ifdef FEAT_QUICKFIX - copy_loclist(oldp, newp); + if (flags & WSP_NEWLOC) + { + /* Don't copy the location list. */ + newp->w_llist = NULL; + newp->w_llist_ref = NULL; + } + else + copy_loclist(oldp, newp); #endif if (oldp->w_localdir != NULL) newp->w_localdir = vim_strsave(oldp->w_localdir); @@ -3220,7 +3229,7 @@ else { /* First window in new tab page, initialize it from "oldwin". */ - win_init(curwin, oldwin); + win_init(curwin, oldwin, 0); # ifdef FEAT_SCROLLBIND /* We don't want scroll-binding in the first window. */ @@ -4028,14 +4037,14 @@ if (mch_dirname(cwd, MAXPATHL) == OK) globaldir = vim_strsave(cwd); } - mch_chdir((char *)curwin->w_localdir); - shorten_fnames(TRUE); + if (mch_chdir((char *)curwin->w_localdir) == 0) + shorten_fnames(TRUE); } else if (globaldir != NULL) { /* Window doesn't have a local directory and we are not in the global * directory: Change to the global directory. */ - mch_chdir((char *)globaldir); + ignored = mch_chdir((char *)globaldir); vim_free(globaldir); globaldir = NULL; shorten_fnames(TRUE); diff -Naur vim72.orig/src/workshop.c vim72/src/workshop.c --- vim72.orig/src/workshop.c 2008-06-21 11:53:26.000000000 -0700 +++ vim72/src/workshop.c 2009-03-22 21:29:08.534315407 -0700 @@ -1121,8 +1121,12 @@ ? (char *)curbuf->b_sfname : ""); #endif - strcpy(ffname, (char *) curbuf->b_ffname); - *filename = ffname; /* copy so nobody can change b_ffname */ + if (curbuf->b_ffname == NULL) + ffname[0] = NUL; + else + /* copy so nobody can change b_ffname */ + strcpy(ffname, (char *) curbuf->b_ffname); + *filename = ffname; *curLine = curwin->w_cursor.lnum; *curCol = curwin->w_cursor.col;