source: patches/vim-7.1-fixes-4.patch@ 6b5cc685

clfs-1.2 clfs-2.1 clfs-3.0.0-systemd clfs-3.0.0-sysvinit systemd sysvinit
Last change on this file since 6b5cc685 was c2aa910, checked in by Jim Gifford <clfs@…>, 17 years ago

Updated vim patch

  • Property mode set to 100644
File size: 243.7 KB
RevLine 
[ba61c16]1Submitted By: Jim Gifford (jim at linuxfromscratch dot org)
[c2aa910]2Date: 10-16-2007
[ba61c16]3Initial Package Version: 7.1
4Origin: Upstream
5Upstream Status: Applied
[c2aa910]6Description: Contains all upstream patches up to 7.1.140
[ba61c16]7 The following patches were skipped
[c2aa910]8 003 007 041 065 070 072 080 088 091 092 124 126 128 129 134
[ba61c16]9
10diff -Naur vim71.orig/runtime/doc/change.txt vim71/runtime/doc/change.txt
11--- vim71.orig/runtime/doc/change.txt 2007-05-12 03:18:46.000000000 -0700
[c2aa910]12+++ vim71/runtime/doc/change.txt 2007-10-16 14:14:06.000000000 -0700
[ba61c16]13@@ -1571,6 +1571,10 @@
14 in their original order, right before the sorted
15 lines.
16
17+ If {pattern} is empty (e.g. // is specified), the
18+ last search pattern is used. This allows trying out
19+ a pattern first.
20+
21 Note that using ":sort" with ":global" doesn't sort the matching lines, it's
22 quite useless.
23
24diff -Naur vim71.orig/runtime/doc/eval.txt vim71/runtime/doc/eval.txt
25--- vim71.orig/runtime/doc/eval.txt 2007-05-12 03:18:46.000000000 -0700
[c2aa910]26+++ vim71/runtime/doc/eval.txt 2007-10-16 14:14:28.000000000 -0700
[ba61c16]27@@ -1,4 +1,4 @@
28-*eval.txt* For Vim version 7.1. Last change: 2007 May 11
[c2aa910]29+*eval.txt* For Vim version 7.1. Last change: 2007 Sep 25
[ba61c16]30
31
32 VIM REFERENCE MANUAL by Bram Moolenaar
33@@ -1557,6 +1557,7 @@
34 changenr() Number current change number
35 char2nr( {expr}) Number ASCII value of first char in {expr}
36 cindent( {lnum}) Number C indent for line {lnum}
37+clearmatches() None clear all matches
38 col( {expr}) Number column nr of cursor or mark
39 complete({startcol}, {matches}) String set Insert mode completion
40 complete_add( {expr}) Number add completion match
[c2aa910]41@@ -1602,7 +1603,7 @@
42 foldtextresult( {lnum}) String text for closed fold at {lnum}
43 foreground( ) Number bring the Vim window to the foreground
44 function( {name}) Funcref reference to function {name}
45-garbagecollect() none free memory, breaking cyclic references
46+garbagecollect( [at_exit]) none free memory, breaking cyclic references
47 get( {list}, {idx} [, {def}]) any get item {idx} from {list} or {def}
48 get( {dict}, {key} [, {def}]) any get item {key} from {dict} or {def}
49 getbufline( {expr}, {lnum} [, {end}])
[ba61c16]50@@ -1622,6 +1623,7 @@
51 getline( {lnum}) String line {lnum} of current buffer
52 getline( {lnum}, {end}) List lines {lnum} to {end} of current buffer
53 getloclist({nr}) List list of location list items
54+getmatches() List list of current matches
55 getpos( {expr}) List position of cursor, mark, etc.
56 getqflist() List list of quickfix items
57 getreg( [{regname} [, 1]]) String contents of register
58@@ -1676,7 +1678,10 @@
59 String check for mappings matching {name}
60 match( {expr}, {pat}[, {start}[, {count}]])
61 Number position where {pat} matches in {expr}
62+matchadd( {group}, {pattern}[, {priority}[, {id}]])
63+ Number highlight {pattern} with {group}
64 matcharg( {nr}) List arguments of |:match|
65+matchdelete( {id}) Number delete match identified by {id}
66 matchend( {expr}, {pat}[, {start}[, {count}]])
67 Number position where {pat} ends in {expr}
68 matchlist( {expr}, {pat}[, {start}[, {count}]])
69@@ -1731,6 +1736,7 @@
70 setline( {lnum}, {line}) Number set line {lnum} to {line}
71 setloclist( {nr}, {list}[, {action}])
72 Number modify location list using {list}
73+setmatches( {list}) Number restore a list of matches
74 setpos( {expr}, {list}) none set the {expr} position to {list}
75 setqflist( {list}[, {action}]) Number modify quickfix list using {list}
76 setreg( {n}, {v}[, {opt}]) Number set register to value and type
77@@ -2012,6 +2018,10 @@
78 feature, -1 is returned.
79 See |C-indenting|.
80
81+clearmatches() *clearmatches()*
82+ Clears all matches previously defined by |matchadd()| and the
83+ |:match| commands.
84+
85 *col()*
86 col({expr}) The result is a Number, which is the byte index of the column
87 position given with {expr}. The accepted positions are:
88@@ -2020,6 +2030,10 @@
89 number of characters in the cursor line plus one)
90 'x position of mark x (if the mark is not set, 0 is
91 returned)
92+ Additionally {expr} can be [lnum, col]: a |List| with the line
93+ and column number. Most useful when the column is "$", to get
94+ the las column of a specific line. When "lnum" or "col" is
95+ out of range then col() returns zero.
96 To get the line number use |line()|. To get both use
97 |getpos()|.
98 For the screen column position use |virtcol()|.
[c2aa910]99@@ -2659,7 +2673,7 @@
100 {name} can be a user defined function or an internal function.
101
102
103-garbagecollect() *garbagecollect()*
104+garbagecollect([at_exit]) *garbagecollect()*
105 Cleanup unused |Lists| and |Dictionaries| that have circular
106 references. There is hardly ever a need to invoke this
107 function, as it is automatically done when Vim runs out of
108@@ -2669,6 +2683,9 @@
109 This is useful if you have deleted a very big |List| and/or
110 |Dictionary| with circular references in a script that runs
111 for a long time.
112+ When the optional "at_exit" argument is one, garbage
113+ collection will also be done when exiting Vim, if it wasn't
114+ done before. This is useful when checking for memory leaks.
115
116 get({list}, {idx} [, {default}]) *get()*
117 Get item {idx} from |List| {list}. When this item is not
118@@ -2824,6 +2841,8 @@
[ba61c16]119 given file {fname}.
120 If {fname} is a directory, 0 is returned.
121 If the file {fname} can't be found, -1 is returned.
122+ If the size of {fname} is too big to fit in a Number then -2
123+ is returned.
124
125 getfontname([{name}]) *getfontname()*
126 Without an argument returns the name of the normal font being
[c2aa910]127@@ -2912,6 +2931,28 @@
[ba61c16]128 returned. For an invalid window number {nr}, an empty list is
129 returned. Otherwise, same as getqflist().
130
131+getmatches() *getmatches()*
132+ Returns a |List| with all matches previously defined by
133+ |matchadd()| and the |:match| commands. |getmatches()| is
134+ useful in combination with |setmatches()|, as |setmatches()|
135+ can restore a list of matches saved by |getmatches()|.
136+ Example: >
137+ :echo getmatches()
138+< [{'group': 'MyGroup1', 'pattern': 'TODO',
139+ 'priority': 10, 'id': 1}, {'group': 'MyGroup2',
140+ 'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
141+ :let m = getmatches()
142+ :call clearmatches()
143+ :echo getmatches()
144+< [] >
145+ :call setmatches(m)
146+ :echo getmatches()
147+< [{'group': 'MyGroup1', 'pattern': 'TODO',
148+ 'priority': 10, 'id': 1}, {'group': 'MyGroup2',
149+ 'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
150+ :unlet m
151+<
152+
153 getqflist() *getqflist()*
154 Returns a list with all the current quickfix errors. Each
155 list item is a dictionary with these entries:
[c2aa910]156@@ -3616,6 +3657,44 @@
[ba61c16]157 the pattern. 'smartcase' is NOT used. The matching is always
158 done like 'magic' is set and 'cpoptions' is empty.
159
160+ *matchadd()* *E798* *E799* *E801*
161+matchadd({group}, {pattern}[, {priority}[, {id}]])
162+ Defines a pattern to be highlighted in the current window (a
163+ "match"). It will be highlighted with {group}. Returns an
164+ identification number (ID), which can be used to delete the
165+ match using |matchdelete()|.
166+
167+ The optional {priority} argument assigns a priority to the
168+ match. A match with a high priority will have its
169+ highlighting overrule that of a match with a lower priority.
170+ A priority is specified as an integer (negative numbers are no
171+ exception). If the {priority} argument is not specified, the
172+ default priority is 10. The priority of 'hlsearch' is zero,
173+ hence all matches with a priority greater than zero will
174+ overrule it. Syntax highlighting (see 'syntax') is a separate
175+ mechanism, and regardless of the chosen priority a match will
176+ always overrule syntax highlighting.
177+
178+ The optional {id} argument allows the request for a specific
179+ match ID. If a specified ID is already taken, an error
180+ message will appear and the match will not be added. An ID
181+ is specified as a positive integer (zero excluded). IDs 1, 2
182+ and 3 are reserved for |:match|, |:2match| and |:3match|,
183+ respectively. If the {id} argument is not specified,
184+ |matchadd()| automatically chooses a free ID.
185+
186+ The number of matches is not limited, as it is the case with
187+ the |:match| commands.
188+
189+ Example: >
190+ :highlight MyGroup ctermbg=green guibg=green
191+ :let m = matchadd("MyGroup", "TODO")
192+< Deletion of the pattern: >
193+ :call matchdelete(m)
194+
195+< A list of matches defined by |matchadd()| and |:match| are
196+ available from |getmatches()|. All matches can be deleted in
197+ one operation by |clearmatches()|.
198
199 matcharg({nr}) *matcharg()*
200 Selects the {nr} match item, as set with a |:match|,
[c2aa910]201@@ -3625,8 +3704,15 @@
[ba61c16]202 The pattern used.
203 When {nr} is not 1, 2 or 3 returns an empty |List|.
204 When there is no match item set returns ['', ''].
205- This is usef to save and restore a |:match|.
206-
207+ This is useful to save and restore a |:match|.
208+ Highlighting matches using the |:match| commands are limited
209+ to three matches. |matchadd()| does not have this limitation.
210+
211+matchdelete({id}) *matchdelete()* *E802* *E803*
212+ Deletes a match with ID {id} previously defined by |matchadd()|
213+ or one of the |:match| commands. Returns 0 if succesfull,
214+ otherwise -1. See example for |matchadd()|. All matches can
215+ be deleted in one operation by |clearmatches()|.
216
217 matchend({expr}, {pat}[, {start}[, {count}]]) *matchend()*
218 Same as match(), but return the index of first character after
[c2aa910]219@@ -4379,7 +4465,13 @@
[ba61c16]220 When {nr} is zero the current window is used. For a location
221 list window, the displayed location list is modified. For an
222 invalid window number {nr}, -1 is returned.
223- Otherwise, same as setqflist().
224+ Otherwise, same as |setqflist()|.
225+ Also see |location-list|.
226+
227+setmatches({list}) *setmatches()*
228+ Restores a list of matches saved by |getmatches()|. Returns 0
229+ if succesfull, otherwise -1. All current matches are cleared
230+ before the list is restored. See example for |getmatches()|.
231
232 *setpos()*
233 setpos({expr}, {list})
[c2aa910]234@@ -5022,14 +5114,12 @@
[ba61c16]235 position, the returned Number will be the column at the end of
236 the <Tab>. For example, for a <Tab> in column 1, with 'ts'
237 set to 8, it returns 8.
238- For the use of {expr} see |col()|. Additionally you can use
239- [lnum, col]: a |List| with the line and column number. When
240- "lnum" or "col" is out of range then virtcol() returns zero.
241- When 'virtualedit' is used it can be [lnum, col, off], where
242+ For the byte position use |col()|.
243+ For the use of {expr} see |col()|.
244+ When 'virtualedit' is used {expr} can be [lnum, col, off], where
245 "off" is the offset in screen columns from the start of the
246 character. E.g., a position within a <Tab> or after the last
247 character.
248- For the byte position use |col()|.
249 When Virtual editing is active in the current mode, a position
250 beyond the end of the line can be returned. |'virtualedit'|
251 The accepted positions are:
252diff -Naur vim71.orig/runtime/doc/options.txt vim71/runtime/doc/options.txt
253--- vim71.orig/runtime/doc/options.txt 2007-05-12 03:18:47.000000000 -0700
[c2aa910]254+++ vim71/runtime/doc/options.txt 2007-10-16 14:14:12.000000000 -0700
[ba61c16]255@@ -1,4 +1,4 @@
256-*options.txt* For Vim version 7.1. Last change: 2007 May 11
257+*options.txt* For Vim version 7.1. Last change: 2007 Aug 10
258
259
260 VIM REFERENCE MANUAL by Bram Moolenaar
261@@ -2415,8 +2415,8 @@
262 When mixing vertically and horizontally split windows, a minimal size
263 is computed and some windows may be larger if there is room. The
264 'eadirection' option tells in which direction the size is affected.
265- Changing the height of a window can be avoided by setting
266- 'winfixheight'.
267+ Changing the height and width of a window can be avoided by setting
268+ 'winfixheight' and 'winfixwidth', respectively.
269
270 *'equalprg'* *'ep'*
271 'equalprg' 'ep' string (default "")
272diff -Naur vim71.orig/runtime/doc/pattern.txt vim71/runtime/doc/pattern.txt
273--- vim71.orig/runtime/doc/pattern.txt 2007-05-12 03:18:47.000000000 -0700
[c2aa910]274+++ vim71/runtime/doc/pattern.txt 2007-10-16 14:14:07.000000000 -0700
[ba61c16]275@@ -1212,7 +1212,10 @@
276 {group} must exist at the moment this command is executed.
277
278 The {group} highlighting still applies when a character is
279- to be highlighted for 'hlsearch'.
280+ to be highlighted for 'hlsearch', as the highlighting for
281+ matches is given higher priority than that of 'hlsearch'.
282+ Syntax highlighting (see 'syntax') is also overruled by
283+ matches.
284
285 Note that highlighting the last used search pattern with
286 'hlsearch' is used in all windows, while the pattern defined
287@@ -1226,8 +1229,15 @@
288 display you may get unexpected results. That is because Vim
289 looks for a match in the line where redrawing starts.
290
291- Also see |matcharg()|, it returns the highlight group and
292- pattern of a previous :match command.
293+ Also see |matcharg()|and |getmatches()|. The former returns
294+ the highlight group and pattern of a previous |:match|
295+ command. The latter returns a list with highlight groups and
296+ patterns defined by both |matchadd()| and |:match|.
297+
298+ Highlighting matches using |:match| are limited to three
299+ matches (aside from |:match|, |:2match| and |:3match|are
300+ available). |matchadd()| does not have this limitation and in
301+ addition makes it possible to prioritize matches.
302
303 Another example, which highlights all characters in virtual
304 column 72 and more: >
305diff -Naur vim71.orig/runtime/doc/pi_paren.txt vim71/runtime/doc/pi_paren.txt
306--- vim71.orig/runtime/doc/pi_paren.txt 2007-05-12 03:18:47.000000000 -0700
[c2aa910]307+++ vim71/runtime/doc/pi_paren.txt 2007-10-16 14:14:20.000000000 -0700
[ba61c16]308@@ -12,8 +12,8 @@
309 You can avoid loading this plugin by setting the "loaded_matchparen" variable: >
310 :let loaded_matchparen = 1
311
312-The plugin installs CursorMoved autocommands to redefine the match
313-highlighting.
314+The plugin installs CursorMoved, CursorMovedI and WinEnter autocommands to
315+redefine the match highlighting.
316
317 To disable the plugin after it was loaded use this command: >
318
319diff -Naur vim71.orig/runtime/doc/usr_41.txt vim71/runtime/doc/usr_41.txt
320--- vim71.orig/runtime/doc/usr_41.txt 2007-05-12 03:18:48.000000000 -0700
[c2aa910]321+++ vim71/runtime/doc/usr_41.txt 2007-10-16 14:14:07.000000000 -0700
[ba61c16]322@@ -763,13 +763,22 @@
323 foldtextresult() get the text displayed for a closed fold
324
325 Syntax and highlighting:
326+ clearmatches() clear all matches defined by |matchadd()| and
327+ the |:match| commands
328+ getmatches() get all matches defined by |matchadd()| and
329+ the |:match| commands
330 hlexists() check if a highlight group exists
331 hlID() get ID of a highlight group
332 synID() get syntax ID at a specific position
333 synIDattr() get a specific attribute of a syntax ID
334 synIDtrans() get translated syntax ID
335 diff_hlID() get highlight ID for diff mode at a position
336+ matchadd() define a pattern to highlight (a "match")
337 matcharg() get info about |:match| arguments
338+ matchdelete() delete a match defined by |matchadd()| or a
339+ |:match| command
340+ setmatches() restore a list of matches saved by
341+ |getmatches()|
342
343 Spelling:
344 spellbadword() locate badly spelled word at or after cursor
345diff -Naur vim71.orig/runtime/doc/windows.txt vim71/runtime/doc/windows.txt
346--- vim71.orig/runtime/doc/windows.txt 2007-05-12 03:18:49.000000000 -0700
[c2aa910]347+++ vim71/runtime/doc/windows.txt 2007-10-16 14:14:12.000000000 -0700
[ba61c16]348@@ -132,7 +132,8 @@
349 the same file. Make new window N high (default is to use half
350 the height of the current window). Reduces the current window
351 height to create room (and others, if the 'equalalways' option
352- is set and 'eadirection' isn't "hor").
353+ is set, 'eadirection' isn't "hor", and one of them is higher
354+ than the current or the new window).
355 Note: CTRL-S does not work on all terminals and might block
356 further input, use CTRL-Q to get going again.
357 Also see |++opt| and |+cmd|.
358@@ -140,9 +141,13 @@
359 CTRL-W CTRL-V *CTRL-W_CTRL-V*
360 CTRL-W v *CTRL-W_v*
361 :[N]vs[plit] [++opt] [+cmd] [file] *:vs* *:vsplit*
362- Like |:split|, but split vertically. If 'equalalways' is set
363- and 'eadirection' isn't "ver" the windows will be spread out
364- horizontally, unless a width was specified.
365+ Like |:split|, but split vertically. The windows will be
366+ spread out horizontally if
367+ 1. a width was not specified,
368+ 2. 'equalalways' is set,
369+ 3. 'eadirection' isn't "ver", and
370+ 4. one of the other windows are wider than the current or new
371+ window.
372 Note: In other places CTRL-Q does the same as CTRL-V, but here
373 it doesn't!
374
375diff -Naur vim71.orig/runtime/filetype.vim vim71/runtime/filetype.vim
376--- vim71.orig/runtime/filetype.vim 2007-05-10 08:14:37.000000000 -0700
[c2aa910]377+++ vim71/runtime/filetype.vim 2007-10-16 14:14:01.000000000 -0700
[ba61c16]378@@ -1,7 +1,7 @@
379 " Vim support file to detect file types
380 "
381 " Maintainer: Bram Moolenaar <Bram@vim.org>
382-" Last Change: 2007 May 10
383+" Last Change: 2007 May 15
384
385 " Listen very carefully, I will say this only once
386 if exists("did_load_filetypes")
387@@ -1286,7 +1286,7 @@
388 au BufNewFile,BufRead *.it,*.ih setf ppwiz
389
390 " Oracle Pro*C/C++
391-au BufNewFile,BufRead .pc setf proc
392+au BufNewFile,BufRead *.pc setf proc
393
394 " Privoxy actions file
395 au BufNewFile,BufRead *.action setf privoxy
396diff -Naur vim71.orig/runtime/plugin/matchparen.vim vim71/runtime/plugin/matchparen.vim
397--- vim71.orig/runtime/plugin/matchparen.vim 2006-10-12 13:05:05.000000000 -0700
[c2aa910]398+++ vim71/runtime/plugin/matchparen.vim 2007-10-16 14:14:20.000000000 -0700
[ba61c16]399@@ -1,6 +1,6 @@
400 " Vim plugin for showing matching parens
401 " Maintainer: Bram Moolenaar <Bram@vim.org>
402-" Last Change: 2006 Oct 12
403+" Last Change: 2007 Aug 8
404
405 " Exit quickly when:
406 " - this plugin was already loaded (or disabled)
407@@ -13,7 +13,7 @@
408
409 augroup matchparen
410 " Replace all matchparen autocommands
411- autocmd! CursorMoved,CursorMovedI * call s:Highlight_Matching_Pair()
412+ autocmd! CursorMoved,CursorMovedI,WinEnter * call s:Highlight_Matching_Pair()
413 augroup END
414
415 " Skip the rest if it was already done.
416@@ -62,25 +62,37 @@
417 " Figure out the arguments for searchpairpos().
418 " Restrict the search to visible lines with "stopline".
419 " And avoid searching very far (e.g., for closed folds and long lines)
420+ " The "viewable" variables give a range in which we can scroll while keeping
421+ " the cursor at the same position
422+ " adjustedScrolloff accounts for very large numbers of scrolloff
423+ let adjustedScrolloff = min([&scrolloff, (line('w$') - line('w0')) / 2])
424+ let bottom_viewable = min([line('$'), c_lnum + &lines - adjustedScrolloff - 2])
425+ let top_viewable = max([1, c_lnum-&lines+adjustedScrolloff + 2])
426+ " one of these stoplines will be adjusted below, but the current values are
427+ " minimal boundaries within the current window
428+ let stoplinebottom = line('w$')
429+ let stoplinetop = line('w0')
430 if i % 2 == 0
431 let s_flags = 'nW'
432 let c2 = plist[i + 1]
433 if has("byte_offset") && has("syntax_items") && &smc > 0
434 let stopbyte = min([line2byte("$"), line2byte(".") + col(".") + &smc * 2])
435- let stopline = min([line('w$'), byte2line(stopbyte)])
436+ let stopline = min([bottom_viewable, byte2line(stopbyte)])
437 else
438- let stopline = min([line('w$'), c_lnum + 100])
439+ let stopline = min([bottom_viewable, c_lnum + 100])
440 endif
441+ let stoplinebottom = stopline
442 else
443 let s_flags = 'nbW'
444 let c2 = c
445 let c = plist[i - 1]
446 if has("byte_offset") && has("syntax_items") && &smc > 0
447 let stopbyte = max([1, line2byte(".") + col(".") - &smc * 2])
448- let stopline = max([line('w0'), byte2line(stopbyte)])
449+ let stopline = max([top_viewable, byte2line(stopbyte)])
450 else
451- let stopline = max([line('w0'), c_lnum - 100])
452+ let stopline = max([top_viewable, c_lnum - 100])
453 endif
454+ let stoplinetop = stopline
455 endif
456 if c == '['
457 let c = '\['
458@@ -106,7 +118,7 @@
459 endif
460
461 " If a match is found setup match highlighting.
462- if m_lnum > 0 && m_lnum >= line('w0') && m_lnum <= line('w$')
463+ if m_lnum > 0 && m_lnum >= stoplinetop && m_lnum <= stoplinebottom
464 exe '3match MatchParen /\(\%' . c_lnum . 'l\%' . (c_col - before) .
465 \ 'c\)\|\(\%' . m_lnum . 'l\%' . m_col . 'c\)/'
466 let w:paren_hl_on = 1
467@@ -114,7 +126,8 @@
468 endfunction
469
470 " Define commands that will disable and enable the plugin.
471-command! NoMatchParen 3match none | unlet! g:loaded_matchparen | au! matchparen
472-command! DoMatchParen runtime plugin/matchparen.vim | doau CursorMoved
473+command! NoMatchParen windo 3match none | unlet! g:loaded_matchparen |
474+ \ au! matchparen
475+command! DoMatchParen runtime plugin/matchparen.vim | windo doau CursorMoved
476
477 let &cpo = cpo_save
478diff -Naur vim71.orig/src/auto/configure vim71/src/auto/configure
479--- vim71.orig/src/auto/configure 2007-05-12 04:49:09.000000000 -0700
[c2aa910]480+++ vim71/src/auto/configure 2007-10-16 14:14:06.000000000 -0700
[ba61c16]481@@ -3843,7 +3843,9 @@
482 fi
483
484 if test "X$vi_cv_path_mzscheme_pfx" != "X"; then
485- if test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
486+ if test "x$MACOSX" = "xyes"; then
487+ MZSCHEME_LIBS="-framework PLT_MzScheme"
488+ elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
489 MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme.a ${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"
490 else
491 MZSCHEME_LIBS="-L${vi_cv_path_mzscheme_pfx}/lib -lmzscheme -lmzgc"
492diff -Naur vim71.orig/src/buffer.c vim71/src/buffer.c
493--- vim71.orig/src/buffer.c 2007-05-10 08:25:59.000000000 -0700
[c2aa910]494+++ vim71/src/buffer.c 2007-10-16 14:14:41.000000000 -0700
[ba61c16]495@@ -171,6 +171,13 @@
496 /* Put the cursor on the first line. */
497 curwin->w_cursor.lnum = 1;
498 curwin->w_cursor.col = 0;
499+
500+ /* Set or reset 'modified' before executing autocommands, so that
501+ * it can be changed there. */
502+ if (!readonlymode && !bufempty())
503+ changed();
504+ else if (retval != FAIL)
505+ unchanged(curbuf, FALSE);
506 #ifdef FEAT_AUTOCMD
507 # ifdef FEAT_EVAL
508 apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, FALSE,
509@@ -194,16 +201,16 @@
510 /* When reading stdin, the buffer contents always needs writing, so set
511 * the changed flag. Unless in readonly mode: "ls | gview -".
512 * When interrupted and 'cpoptions' contains 'i' set changed flag. */
513- if ((read_stdin && !readonlymode && !bufempty())
514+ if ((got_int && vim_strchr(p_cpo, CPO_INTMOD) != NULL)
515 #ifdef FEAT_AUTOCMD
516 || modified_was_set /* ":set modified" used in autocmd */
517 # ifdef FEAT_EVAL
518 || (aborting() && vim_strchr(p_cpo, CPO_INTMOD) != NULL)
519 # endif
520 #endif
521- || (got_int && vim_strchr(p_cpo, CPO_INTMOD) != NULL))
522+ )
523 changed();
524- else if (retval != FAIL)
525+ else if (retval != FAIL && !read_stdin)
526 unchanged(curbuf, FALSE);
527 save_file_ff(curbuf); /* keep this fileformat */
528
529@@ -495,6 +502,7 @@
530 buf->b_start_eol = TRUE;
531 #ifdef FEAT_MBYTE
532 buf->b_p_bomb = FALSE;
533+ buf->b_start_bomb = FALSE;
534 #endif
535 buf->b_ml.ml_mfp = NULL;
536 buf->b_ml.ml_flags = ML_EMPTY; /* empty buffer */
[c2aa910]537@@ -4167,29 +4175,35 @@
538 * mess up the full path name, even though it starts with a '/'.
539 * Also expand when there is ".." in the file name, try to remove it,
540 * because "c:/src/../README" is equal to "c:/README".
541+ * Similarly "c:/src//file" is equal to "c:/src/file".
542 * For MS-Windows also expand names like "longna~1" to "longname".
543 */
544 #ifdef UNIX
545 return FullName_save(fname, TRUE);
546 #else
547- if (!vim_isAbsName(fname) || strstr((char *)fname, "..") != NULL
548-#if defined(MSWIN) || defined(DJGPP)
549+ if (!vim_isAbsName(fname)
550+ || strstr((char *)fname, "..") != NULL
551+ || strstr((char *)fname, "//") != NULL
552+# ifdef BACKSLASH_IN_FILENAME
553+ || strstr((char *)fname, "\\\\") != NULL
554+# endif
555+# if defined(MSWIN) || defined(DJGPP)
556 || vim_strchr(fname, '~') != NULL
557-#endif
558+# endif
559 )
560 return FullName_save(fname, FALSE);
561
562 fname = vim_strsave(fname);
563
564-#ifdef USE_FNAME_CASE
565-# ifdef USE_LONG_FNAME
566+# ifdef USE_FNAME_CASE
567+# ifdef USE_LONG_FNAME
568 if (USE_LONG_FNAME)
569-# endif
570+# endif
571 {
572 if (fname != NULL)
573 fname_case(fname, 0); /* set correct case for file name */
574 }
575-#endif
576+# endif
577
578 return fname;
579 #endif
580@@ -4853,7 +4867,7 @@
[ba61c16]581 */
582 for (e = s; *e != ':' && *e != NUL; ++e)
583 if (e[0] == '\\' && e[1] == ':')
584- STRCPY(e, e + 1);
585+ mch_memmove(e, e + 1, STRLEN(e));
586 if (*e == NUL)
587 end = TRUE;
588
[c2aa910]589@@ -5507,11 +5521,11 @@
590
591 #ifdef FEAT_AUTOCMD
592 if (!aucmd) /* Don't trigger BufDelete autocommands here. */
593- ++autocmd_block;
594+ block_autocmds();
595 #endif
596 close_buffer(NULL, buf, DOBUF_WIPE);
597 #ifdef FEAT_AUTOCMD
598 if (!aucmd)
599- --autocmd_block;
600+ unblock_autocmds();
601 #endif
602 }
[ba61c16]603diff -Naur vim71.orig/src/charset.c vim71/src/charset.c
604--- vim71.orig/src/charset.c 2007-03-24 13:10:37.000000000 -0700
[c2aa910]605+++ vim71/src/charset.c 2007-10-16 14:14:20.000000000 -0700
[ba61c16]606@@ -207,7 +207,10 @@
607 }
608 while (c <= c2)
609 {
610- if (!do_isalpha || isalpha(c)
611+ /* Use the MB_ functions here, because isalpha() doesn't
612+ * work properly when 'encoding' is "latin1" and the locale is
613+ * "C". */
614+ if (!do_isalpha || MB_ISLOWER(c) || MB_ISUPPER(c)
615 #ifdef FEAT_FKMAP
616 || (p_altkeymap && (F_isalpha(c) || F_isdigit(c)))
617 #endif
618@@ -929,6 +932,23 @@
619 }
620
621 /*
622+ * return TRUE if 'c' is a valid file-name character or a wildcard character
623+ * Assume characters above 0x100 are valid (multi-byte).
624+ * Explicitly interpret ']' as a wildcard character as mch_has_wildcard("]")
625+ * returns false.
626+ */
627+ int
628+vim_isfilec_or_wc(c)
629+ int c;
630+{
631+ char_u buf[2];
632+
633+ buf[0] = (char_u)c;
634+ buf[1] = NUL;
635+ return vim_isfilec(c) || c == ']' || mch_has_wildcard(buf);
636+}
637+
638+/*
639 * return TRUE if 'c' is a printable character
640 * Assume characters above 0x100 are printable (multi-byte), except for
641 * Unicode.
642@@ -1898,7 +1918,7 @@
643 {
644 for ( ; *p; ++p)
645 if (rem_backslash(p))
646- STRCPY(p, p + 1);
647+ mch_memmove(p, p + 1, STRLEN(p));
648 }
649
650 /*
651diff -Naur vim71.orig/src/configure.in vim71/src/configure.in
652--- vim71.orig/src/configure.in 2007-05-12 02:19:27.000000000 -0700
[c2aa910]653+++ vim71/src/configure.in 2007-10-16 14:14:06.000000000 -0700
[ba61c16]654@@ -423,7 +423,9 @@
655 fi
656
657 if test "X$vi_cv_path_mzscheme_pfx" != "X"; then
658- if test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
659+ if test "x$MACOSX" = "xyes"; then
660+ MZSCHEME_LIBS="-framework PLT_MzScheme"
661+ elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
662 MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme.a ${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"
663 else
664 MZSCHEME_LIBS="-L${vi_cv_path_mzscheme_pfx}/lib -lmzscheme -lmzgc"
[c2aa910]665diff -Naur vim71.orig/src/diff.c vim71/src/diff.c
666--- vim71.orig/src/diff.c 2007-02-15 16:18:41.000000000 -0800
667+++ vim71/src/diff.c 2007-10-16 14:14:31.000000000 -0700
668@@ -840,11 +840,11 @@
669 tmp_orig, tmp_new);
670 append_redir(cmd, p_srr, tmp_diff);
671 #ifdef FEAT_AUTOCMD
672- ++autocmd_block; /* Avoid ShellCmdPost stuff */
673+ block_autocmds(); /* Avoid ShellCmdPost stuff */
674 #endif
675 (void)call_shell(cmd, SHELL_FILTER|SHELL_SILENT|SHELL_DOOUT);
676 #ifdef FEAT_AUTOCMD
677- --autocmd_block;
678+ unblock_autocmds();
679 #endif
680 vim_free(cmd);
681 }
682@@ -949,11 +949,11 @@
683 # endif
684 eap->arg);
685 #ifdef FEAT_AUTOCMD
686- ++autocmd_block; /* Avoid ShellCmdPost stuff */
687+ block_autocmds(); /* Avoid ShellCmdPost stuff */
688 #endif
689 (void)call_shell(buf, SHELL_FILTER | SHELL_COOKED);
690 #ifdef FEAT_AUTOCMD
691- --autocmd_block;
692+ unblock_autocmds();
693 #endif
694 }
695
[ba61c16]696diff -Naur vim71.orig/src/digraph.c vim71/src/digraph.c
697--- vim71.orig/src/digraph.c 2006-05-02 11:24:04.000000000 -0700
[c2aa910]698+++ vim71/src/digraph.c 2007-10-16 14:14:28.000000000 -0700
699@@ -2028,7 +2028,7 @@
700
701 ++no_mapping;
702 ++allow_keys;
703- c = safe_vgetc();
704+ c = plain_vgetc();
705 --no_mapping;
706 --allow_keys;
707 if (c != ESC) /* ESC cancels CTRL-K */
708@@ -2050,7 +2050,7 @@
709 #endif
710 ++no_mapping;
711 ++allow_keys;
712- cc = safe_vgetc();
713+ cc = plain_vgetc();
714 --no_mapping;
715 --allow_keys;
716 if (cc != ESC) /* ESC cancels CTRL-K */
[ba61c16]717@@ -2349,8 +2349,10 @@
718
719 if (*curbuf->b_p_keymap == NUL)
720 {
721- /* Stop any active keymap and clear the table. */
722+ /* Stop any active keymap and clear the table. Also remove
[c2aa910]723+ * b:keymap_name, as no keymap is active now. */
[ba61c16]724 keymap_unload();
725+ do_cmdline_cmd((char_u *)"unlet! b:keymap_name");
726 }
727 else
728 {
729@@ -2500,7 +2502,6 @@
730
731 ga_clear(&curbuf->b_kmap_ga);
732 curbuf->b_kmap_state &= ~KEYMAP_LOADED;
733- do_cmdline_cmd((char_u *)"unlet! b:keymap_name");
734 #ifdef FEAT_WINDOWS
735 status_redraw_curbuf();
736 #endif
737diff -Naur vim71.orig/src/edit.c vim71/src/edit.c
738--- vim71.orig/src/edit.c 2007-05-07 12:43:55.000000000 -0700
[c2aa910]739+++ vim71/src/edit.c 2007-10-16 14:14:28.000000000 -0700
740@@ -788,7 +788,7 @@
741 ins_redraw(FALSE);
742 ++no_mapping;
743 ++allow_keys;
744- c = safe_vgetc();
745+ c = plain_vgetc();
746 --no_mapping;
747 --allow_keys;
748 if (c != Ctrl_N && c != Ctrl_G && c != Ctrl_O)
749@@ -981,7 +981,7 @@
750 #ifdef FEAT_NETBEANS_INTG
751 case K_F21: /* NetBeans command */
752 ++no_mapping; /* don't map the next key hits */
753- i = safe_vgetc();
754+ i = plain_vgetc();
755 --no_mapping;
756 netbeans_keycommand(i);
757 break;
[ba61c16]758@@ -2057,7 +2057,6 @@
759 * case of the originally typed text is used, and the case of the completed
760 * text is inferred, ie this tries to work out what case you probably wanted
761 * the rest of the word to be in -- webb
762- * TODO: make this work for multi-byte characters.
763 */
764 int
765 ins_compl_add_infercase(str, len, icase, fname, dir, flags)
766@@ -2068,54 +2067,147 @@
767 int dir;
768 int flags;
769 {
770+ char_u *p;
771+ int i, c;
772+ int actual_len; /* Take multi-byte characters */
773+ int actual_compl_length; /* into account. */
774+ int *wca; /* Wide character array. */
775 int has_lower = FALSE;
776 int was_letter = FALSE;
777- int idx;
778
779- if (p_ic && curbuf->b_p_inf && len < IOSIZE)
780+ if (p_ic && curbuf->b_p_inf)
781 {
782- /* Infer case of completed part -- webb */
783- /* Use IObuff, str would change text in buffer! */
784- vim_strncpy(IObuff, str, len);
785+ /* Infer case of completed part. */
786
787- /* Rule 1: Were any chars converted to lower? */
788- for (idx = 0; idx < compl_length; ++idx)
789+ /* Find actual length of completion. */
790+#ifdef FEAT_MBYTE
791+ if (has_mbyte)
792 {
793- if (islower(compl_orig_text[idx]))
794+ p = str;
795+ actual_len = 0;
796+ while (*p != NUL)
797 {
798- has_lower = TRUE;
799- if (isupper(IObuff[idx]))
800- {
801- /* Rule 1 is satisfied */
802- for (idx = compl_length; idx < len; ++idx)
803- IObuff[idx] = TOLOWER_LOC(IObuff[idx]);
804- break;
805- }
806+ mb_ptr_adv(p);
807+ ++actual_len;
808 }
809 }
810+ else
811+#endif
812+ actual_len = len;
813
814- /*
815- * Rule 2: No lower case, 2nd consecutive letter converted to
816- * upper case.
817- */
818- if (!has_lower)
819+ /* Find actual length of original text. */
820+#ifdef FEAT_MBYTE
821+ if (has_mbyte)
[c2aa910]822 {
823- for (idx = 0; idx < compl_length; ++idx)
[ba61c16]824+ p = compl_orig_text;
825+ actual_compl_length = 0;
826+ while (*p != NUL)
[c2aa910]827 {
828- if (was_letter && isupper(compl_orig_text[idx])
829- && islower(IObuff[idx]))
[ba61c16]830+ mb_ptr_adv(p);
831+ ++actual_compl_length;
832+ }
833+ }
834+ else
835+#endif
836+ actual_compl_length = compl_length;
837+
838+ /* Allocate wide character array for the completion and fill it. */
839+ wca = (int *)alloc(actual_len * sizeof(int));
840+ if (wca != NULL)
[c2aa910]841+ {
[ba61c16]842+ p = str;
843+ for (i = 0; i < actual_len; ++i)
844+#ifdef FEAT_MBYTE
845+ if (has_mbyte)
846+ wca[i] = mb_ptr2char_adv(&p);
847+ else
848+#endif
849+ wca[i] = *(p++);
850+
851+ /* Rule 1: Were any chars converted to lower? */
852+ p = compl_orig_text;
853+ for (i = 0; i < actual_compl_length; ++i)
[c2aa910]854+ {
[ba61c16]855+#ifdef FEAT_MBYTE
856+ if (has_mbyte)
857+ c = mb_ptr2char_adv(&p);
858+ else
859+#endif
860+ c = *(p++);
861+ if (MB_ISLOWER(c))
862 {
863- /* Rule 2 is satisfied */
864- for (idx = compl_length; idx < len; ++idx)
865- IObuff[idx] = TOUPPER_LOC(IObuff[idx]);
866- break;
867+ has_lower = TRUE;
868+ if (MB_ISUPPER(wca[i]))
869+ {
870+ /* Rule 1 is satisfied. */
871+ for (i = actual_compl_length; i < actual_len; ++i)
872+ wca[i] = MB_TOLOWER(wca[i]);
873+ break;
874+ }
875 }
876- was_letter = isalpha(compl_orig_text[idx]);
877 }
878- }
879
880- /* Copy the original case of the part we typed */
881- STRNCPY(IObuff, compl_orig_text, compl_length);
882+ /*
883+ * Rule 2: No lower case, 2nd consecutive letter converted to
884+ * upper case.
885+ */
886+ if (!has_lower)
887+ {
888+ p = compl_orig_text;
889+ for (i = 0; i < actual_compl_length; ++i)
890+ {
891+#ifdef FEAT_MBYTE
892+ if (has_mbyte)
893+ c = mb_ptr2char_adv(&p);
894+ else
895+#endif
896+ c = *(p++);
897+ if (was_letter && MB_ISUPPER(c) && MB_ISLOWER(wca[i]))
898+ {
899+ /* Rule 2 is satisfied. */
900+ for (i = actual_compl_length; i < actual_len; ++i)
901+ wca[i] = MB_TOUPPER(wca[i]);
902+ break;
903+ }
904+ was_letter = MB_ISLOWER(c) || MB_ISUPPER(c);
905+ }
906+ }
907+
908+ /* Copy the original case of the part we typed. */
909+ p = compl_orig_text;
910+ for (i = 0; i < actual_compl_length; ++i)
911+ {
912+#ifdef FEAT_MBYTE
913+ if (has_mbyte)
914+ c = mb_ptr2char_adv(&p);
915+ else
916+#endif
917+ c = *(p++);
918+ if (MB_ISLOWER(c))
919+ wca[i] = MB_TOLOWER(wca[i]);
920+ else if (MB_ISUPPER(c))
921+ wca[i] = MB_TOUPPER(wca[i]);
922+ }
923+
924+ /*
925+ * Generate encoding specific output from wide character array.
926+ * Multi-byte characters can occupy up to five bytes more than
927+ * ASCII characters, and we also need one byte for NUL, so stay
928+ * six bytes away from the edge of IObuff.
929+ */
930+ p = IObuff;
931+ i = 0;
932+ while (i < actual_len && (p - IObuff + 6) < IOSIZE)
933+#ifdef FEAT_MBYTE
934+ if (has_mbyte)
935+ p += mb_char2bytes(wca[i++], p);
936+ else
937+#endif
938+ *(p++) = wca[i++];
939+ *p = NUL;
940+
941+ vim_free(wca);
942+ }
943
944 return ins_compl_add(IObuff, len, icase, fname, NULL, dir,
945 flags, FALSE);
946@@ -2842,6 +2934,7 @@
947 /*
948 * Add the other matches on the line
949 */
950+ ptr = buf;
951 while (!got_int)
952 {
953 /* Find start of the next word. Skip white
954@@ -2851,7 +2944,7 @@
955 break;
956 wstart = ptr;
957
958- /* Find end of the word and add it. */
959+ /* Find end of the word. */
960 #ifdef FEAT_MBYTE
961 if (has_mbyte)
962 /* Japanese words may have characters in
963@@ -2868,9 +2961,12 @@
964 else
965 #endif
966 ptr = find_word_end(ptr);
967- add_r = ins_compl_add_infercase(wstart,
968- (int)(ptr - wstart),
969- p_ic, files[i], *dir, 0);
970+
971+ /* Add the word. Skip the regexp match. */
972+ if (wstart != regmatch->startp[0])
973+ add_r = ins_compl_add_infercase(wstart,
974+ (int)(ptr - wstart),
975+ p_ic, files[i], *dir, 0);
976 }
977 }
978 if (add_r == OK)
[c2aa910]979@@ -5128,10 +5224,7 @@
980 i = 0;
981 for (;;)
982 {
983- do
984- nc = safe_vgetc();
985- while (nc == K_IGNORE || nc == K_VER_SCROLLBAR
986- || nc == K_HOR_SCROLLBAR);
987+ nc = plain_vgetc();
988 #ifdef FEAT_CMDL_INFO
989 if (!(State & CMDLINE)
990 # ifdef FEAT_MBYTE
991@@ -7215,6 +7308,8 @@
[ba61c16]992 p = ml_get_curline();
993 if (cin_iscase(p) || cin_isscopedecl(p) || cin_islabel(30))
994 return TRUE;
995+ /* Need to get the line again after cin_islabel(). */
996+ p = ml_get_curline();
997 if (curwin->w_cursor.col > 2
998 && p[curwin->w_cursor.col - 1] == ':'
999 && p[curwin->w_cursor.col - 2] == ':')
[c2aa910]1000@@ -7477,7 +7572,7 @@
1001 * deleted when ESC is hit.
1002 */
1003 ++no_mapping;
1004- regname = safe_vgetc();
1005+ regname = plain_vgetc();
1006 #ifdef FEAT_LANGMAP
1007 LANGMAP_ADJUST(regname, TRUE);
1008 #endif
1009@@ -7488,7 +7583,7 @@
1010 #ifdef FEAT_CMDL_INFO
1011 add_to_showcmd_c(literally);
1012 #endif
1013- regname = safe_vgetc();
1014+ regname = plain_vgetc();
1015 #ifdef FEAT_LANGMAP
1016 LANGMAP_ADJUST(regname, TRUE);
1017 #endif
1018@@ -7579,7 +7674,7 @@
1019 * deleted when ESC is hit.
1020 */
1021 ++no_mapping;
1022- c = safe_vgetc();
1023+ c = plain_vgetc();
1024 --no_mapping;
1025 switch (c)
1026 {
1027@@ -7998,7 +8093,8 @@
[ba61c16]1028 /*
1029 * 0^D and ^^D: remove all indent.
1030 */
1031- if ((lastc == '0' || lastc == '^') && curwin->w_cursor.col)
1032+ if (c == Ctrl_D && (lastc == '0' || lastc == '^')
1033+ && curwin->w_cursor.col > 0)
1034 {
1035 --curwin->w_cursor.col;
1036 (void)del_char(FALSE); /* delete the '^' or '0' */
[c2aa910]1037@@ -9257,7 +9353,7 @@
1038 * mode message to be deleted when ESC is hit */
1039 ++no_mapping;
1040 ++allow_keys;
1041- c = safe_vgetc();
1042+ c = plain_vgetc();
1043 --no_mapping;
1044 --allow_keys;
1045 if (IS_SPECIAL(c) || mod_mask) /* special key */
1046@@ -9289,7 +9385,7 @@
1047 }
1048 ++no_mapping;
1049 ++allow_keys;
1050- cc = safe_vgetc();
1051+ cc = plain_vgetc();
1052 --no_mapping;
1053 --allow_keys;
1054 if (cc != ESC)
[ba61c16]1055diff -Naur vim71.orig/src/eval.c vim71/src/eval.c
1056--- vim71.orig/src/eval.c 2007-05-07 12:47:32.000000000 -0700
[c2aa910]1057+++ vim71/src/eval.c 2007-10-16 14:14:38.000000000 -0700
[ba61c16]1058@@ -369,17 +369,17 @@
1059 static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars));
1060 static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon));
1061 static char_u *skip_var_one __ARGS((char_u *arg));
1062-static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty));
1063-static void list_glob_vars __ARGS((void));
1064-static void list_buf_vars __ARGS((void));
1065-static void list_win_vars __ARGS((void));
1066+static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty, int *first));
1067+static void list_glob_vars __ARGS((int *first));
1068+static void list_buf_vars __ARGS((int *first));
1069+static void list_win_vars __ARGS((int *first));
1070 #ifdef FEAT_WINDOWS
1071-static void list_tab_vars __ARGS((void));
1072+static void list_tab_vars __ARGS((int *first));
1073 #endif
1074-static void list_vim_vars __ARGS((void));
1075-static void list_script_vars __ARGS((void));
1076-static void list_func_vars __ARGS((void));
1077-static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg));
1078+static void list_vim_vars __ARGS((int *first));
1079+static void list_script_vars __ARGS((int *first));
1080+static void list_func_vars __ARGS((int *first));
1081+static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg, int *first));
1082 static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op));
1083 static int check_changedtick __ARGS((char_u *arg));
1084 static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags));
1085@@ -475,6 +475,7 @@
1086 static void f_changenr __ARGS((typval_T *argvars, typval_T *rettv));
1087 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv));
1088 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv));
1089+static void f_clearmatches __ARGS((typval_T *argvars, typval_T *rettv));
1090 static void f_col __ARGS((typval_T *argvars, typval_T *rettv));
1091 #if defined(FEAT_INS_EXPAND)
1092 static void f_complete __ARGS((typval_T *argvars, typval_T *rettv));
1093@@ -529,6 +530,7 @@
1094 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv));
1095 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv));
1096 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv));
1097+static void f_getmatches __ARGS((typval_T *argvars, typval_T *rettv));
1098 static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv));
1099 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv));
1100 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv));
1101@@ -577,7 +579,9 @@
1102 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv));
1103 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv));
1104 static void f_match __ARGS((typval_T *argvars, typval_T *rettv));
1105+static void f_matchadd __ARGS((typval_T *argvars, typval_T *rettv));
1106 static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv));
1107+static void f_matchdelete __ARGS((typval_T *argvars, typval_T *rettv));
1108 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv));
1109 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv));
1110 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv));
1111@@ -618,6 +622,7 @@
1112 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv));
1113 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv));
1114 static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv));
1115+static void f_setmatches __ARGS((typval_T *argvars, typval_T *rettv));
1116 static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv));
1117 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv));
1118 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv));
1119@@ -672,7 +677,7 @@
1120 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv));
1121
1122 static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump));
1123-static pos_T *var2fpos __ARGS((typval_T *varp, int lnum, int *fnum));
1124+static pos_T *var2fpos __ARGS((typval_T *varp, int dollar_lnum, int *fnum));
1125 static int get_env_len __ARGS((char_u **arg));
1126 static int get_id_len __ARGS((char_u **arg));
1127 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose));
1128@@ -699,8 +704,8 @@
1129 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname));
1130 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val));
1131 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi));
1132-static void list_one_var __ARGS((dictitem_T *v, char_u *prefix));
1133-static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string));
1134+static void list_one_var __ARGS((dictitem_T *v, char_u *prefix, int *first));
1135+static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string, int *first));
1136 static void set_var __ARGS((char_u *name, typval_T *varp, int copy));
1137 static int var_check_ro __ARGS((int flags, char_u *name));
1138 static int var_check_fixed __ARGS((int flags, char_u *name));
1139@@ -992,20 +997,20 @@
1140 char_u *value;
1141 int value_len;
1142 {
1143- size_t len;
1144+ int len;
1145
1146 if (redir_lval == NULL)
1147 return;
1148
1149 if (value_len == -1)
1150- len = STRLEN(value); /* Append the entire string */
1151+ len = (int)STRLEN(value); /* Append the entire string */
1152 else
1153- len = value_len; /* Append only "value_len" characters */
1154+ len = value_len; /* Append only "value_len" characters */
1155
1156- if (ga_grow(&redir_ga, (int)len) == OK)
1157+ if (ga_grow(&redir_ga, len) == OK)
1158 {
1159 mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len);
1160- redir_ga.ga_len += (int)len;
1161+ redir_ga.ga_len += len;
1162 }
1163 else
1164 var_redir_stop();
[c2aa910]1165@@ -1313,7 +1318,6 @@
1166 {
1167 hashitem_T *hi;
1168
1169- clear_tv(&vimvars[idx].vv_tv);
1170 vimvars[idx].vv_tv = *save_tv;
1171 if (vimvars[idx].vv_type == VAR_UNKNOWN)
1172 {
1173@@ -1357,7 +1361,6 @@
1174
1175 if (p_verbose == 0)
1176 --emsg_off;
1177- vimvars[VV_VAL].vv_str = NULL;
1178 restore_vimvar(VV_VAL, &save_val);
1179
1180 return list;
1181@@ -1411,7 +1414,8 @@
[ba61c16]1182 }
1183
1184
1185-#if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO)
1186+#if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) \
1187+ || defined(FEAT_COMPL_FUNC) || defined(PROTO)
1188 /*
1189 * Call some vimL function and return the result in "*rettv".
1190 * Uses argv[argc] for the function arguments.
[c2aa910]1191@@ -1484,6 +1488,7 @@
[ba61c16]1192 return ret;
1193 }
1194
1195+# if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO)
1196 /*
1197 * Call vimL function "func" and return the result as a string.
1198 * Returns NULL when calling the function fails.
[c2aa910]1199@@ -1506,8 +1511,9 @@
[ba61c16]1200 clear_tv(&rettv);
1201 return retval;
1202 }
1203+# endif
1204
1205-#if defined(FEAT_COMPL_FUNC) || defined(PROTO)
1206+# if defined(FEAT_COMPL_FUNC) || defined(PROTO)
1207 /*
1208 * Call vimL function "func" and return the result as a number.
1209 * Returns -1 when calling the function fails.
[c2aa910]1210@@ -1530,7 +1536,7 @@
[ba61c16]1211 clear_tv(&rettv);
1212 return retval;
1213 }
1214-#endif
1215+# endif
1216
1217 /*
1218 * Call vimL function "func" and return the result as a list
[c2aa910]1219@@ -1556,9 +1562,9 @@
[ba61c16]1220
1221 return rettv.vval.v_list;
1222 }
1223-
1224 #endif
1225
1226+
1227 /*
1228 * Save the current function call pointer, and set it to NULL.
1229 * Used when executing autocommands and for ":source".
[c2aa910]1230@@ -1691,6 +1697,7 @@
[ba61c16]1231 int semicolon = 0;
1232 char_u op[2];
1233 char_u *argend;
1234+ int first = TRUE;
1235
1236 argend = skip_var_list(arg, &var_count, &semicolon);
1237 if (argend == NULL)
[c2aa910]1238@@ -1707,19 +1714,19 @@
[ba61c16]1239 EMSG(_(e_invarg));
1240 else if (!ends_excmd(*arg))
1241 /* ":let var1 var2" */
1242- arg = list_arg_vars(eap, arg);
1243+ arg = list_arg_vars(eap, arg, &first);
1244 else if (!eap->skip)
1245 {
1246 /* ":let" */
1247- list_glob_vars();
1248- list_buf_vars();
1249- list_win_vars();
1250+ list_glob_vars(&first);
1251+ list_buf_vars(&first);
1252+ list_win_vars(&first);
1253 #ifdef FEAT_WINDOWS
1254- list_tab_vars();
1255+ list_tab_vars(&first);
1256 #endif
1257- list_script_vars();
1258- list_func_vars();
1259- list_vim_vars();
1260+ list_script_vars(&first);
1261+ list_func_vars(&first);
1262+ list_vim_vars(&first);
1263 }
1264 eap->nextcmd = check_nextcmd(arg);
1265 }
[c2aa910]1266@@ -1924,10 +1931,11 @@
[ba61c16]1267 * If "empty" is TRUE also list NULL strings as empty strings.
1268 */
1269 static void
1270-list_hashtable_vars(ht, prefix, empty)
1271+list_hashtable_vars(ht, prefix, empty, first)
1272 hashtab_T *ht;
1273 char_u *prefix;
1274 int empty;
1275+ int *first;
1276 {
1277 hashitem_T *hi;
1278 dictitem_T *di;
[c2aa910]1279@@ -1942,7 +1950,7 @@
[ba61c16]1280 di = HI2DI(hi);
1281 if (empty || di->di_tv.v_type != VAR_STRING
1282 || di->di_tv.vval.v_string != NULL)
1283- list_one_var(di, prefix);
1284+ list_one_var(di, prefix, first);
1285 }
1286 }
1287 }
[c2aa910]1288@@ -1951,32 +1959,38 @@
[ba61c16]1289 * List global variables.
1290 */
1291 static void
1292-list_glob_vars()
1293+list_glob_vars(first)
1294+ int *first;
1295 {
1296- list_hashtable_vars(&globvarht, (char_u *)"", TRUE);
1297+ list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first);
1298 }
1299
1300 /*
1301 * List buffer variables.
1302 */
1303 static void
1304-list_buf_vars()
1305+list_buf_vars(first)
1306+ int *first;
1307 {
1308 char_u numbuf[NUMBUFLEN];
1309
1310- list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE);
1311+ list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:",
1312+ TRUE, first);
1313
1314 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick);
1315- list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf);
1316+ list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER,
1317+ numbuf, first);
1318 }
1319
1320 /*
1321 * List window variables.
1322 */
1323 static void
1324-list_win_vars()
1325+list_win_vars(first)
1326+ int *first;
1327 {
1328- list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE);
1329+ list_hashtable_vars(&curwin->w_vars.dv_hashtab,
1330+ (char_u *)"w:", TRUE, first);
1331 }
1332
1333 #ifdef FEAT_WINDOWS
[c2aa910]1334@@ -1984,9 +1998,11 @@
[ba61c16]1335 * List tab page variables.
1336 */
1337 static void
1338-list_tab_vars()
1339+list_tab_vars(first)
1340+ int *first;
1341 {
1342- list_hashtable_vars(&curtab->tp_vars.dv_hashtab, (char_u *)"t:", TRUE);
1343+ list_hashtable_vars(&curtab->tp_vars.dv_hashtab,
1344+ (char_u *)"t:", TRUE, first);
1345 }
1346 #endif
1347
[c2aa910]1348@@ -1994,39 +2010,44 @@
[ba61c16]1349 * List Vim variables.
1350 */
1351 static void
1352-list_vim_vars()
1353+list_vim_vars(first)
1354+ int *first;
1355 {
1356- list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE);
1357+ list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first);
1358 }
1359
1360 /*
1361 * List script-local variables, if there is a script.
1362 */
1363 static void
1364-list_script_vars()
1365+list_script_vars(first)
1366+ int *first;
1367 {
1368 if (current_SID > 0 && current_SID <= ga_scripts.ga_len)
1369- list_hashtable_vars(&SCRIPT_VARS(current_SID), (char_u *)"s:", FALSE);
1370+ list_hashtable_vars(&SCRIPT_VARS(current_SID),
1371+ (char_u *)"s:", FALSE, first);
1372 }
1373
1374 /*
1375 * List function variables, if there is a function.
1376 */
1377 static void
1378-list_func_vars()
1379+list_func_vars(first)
1380+ int *first;
1381 {
1382 if (current_funccal != NULL)
1383 list_hashtable_vars(&current_funccal->l_vars.dv_hashtab,
1384- (char_u *)"l:", FALSE);
1385+ (char_u *)"l:", FALSE, first);
1386 }
1387
1388 /*
1389 * List variables in "arg".
1390 */
1391 static char_u *
1392-list_arg_vars(eap, arg)
1393+list_arg_vars(eap, arg, first)
1394 exarg_T *eap;
1395 char_u *arg;
1396+ int *first;
1397 {
1398 int error = FALSE;
1399 int len;
[c2aa910]1400@@ -2083,15 +2104,15 @@
[ba61c16]1401 {
1402 switch (*name)
1403 {
1404- case 'g': list_glob_vars(); break;
1405- case 'b': list_buf_vars(); break;
1406- case 'w': list_win_vars(); break;
1407+ case 'g': list_glob_vars(first); break;
1408+ case 'b': list_buf_vars(first); break;
1409+ case 'w': list_win_vars(first); break;
1410 #ifdef FEAT_WINDOWS
1411- case 't': list_tab_vars(); break;
1412+ case 't': list_tab_vars(first); break;
1413 #endif
1414- case 'v': list_vim_vars(); break;
1415- case 's': list_script_vars(); break;
1416- case 'l': list_func_vars(); break;
1417+ case 'v': list_vim_vars(first); break;
1418+ case 's': list_script_vars(first); break;
1419+ case 'l': list_func_vars(first); break;
1420 default:
1421 EMSG2(_("E738: Can't list variables for %s"), name);
1422 }
[c2aa910]1423@@ -2108,7 +2129,9 @@
[ba61c16]1424 *arg = NUL;
1425 list_one_var_a((char_u *)"",
1426 arg == arg_subsc ? name : name_start,
1427- tv.v_type, s == NULL ? (char_u *)"" : s);
1428+ tv.v_type,
1429+ s == NULL ? (char_u *)"" : s,
1430+ first);
1431 *arg = c;
1432 vim_free(tf);
1433 }
[c2aa910]1434@@ -6105,6 +6128,7 @@
1435 /* Only do this once. */
1436 want_garbage_collect = FALSE;
1437 may_garbage_collect = FALSE;
1438+ garbage_collect_at_exit = FALSE;
1439
1440 /*
1441 * 1. Go through all accessible variables and mark all lists and dicts
1442@@ -6681,7 +6705,7 @@
1443 dict_T *d = NULL;
1444 typval_T tvkey;
1445 typval_T tv;
1446- char_u *key;
1447+ char_u *key = NULL;
1448 dictitem_T *item;
1449 char_u *start = skipwhite(*arg + 1);
1450 char_u buf[NUMBUFLEN];
1451@@ -6721,20 +6745,24 @@
1452 clear_tv(&tvkey);
1453 goto failret;
1454 }
1455- key = get_tv_string_buf_chk(&tvkey, buf);
1456- if (key == NULL || *key == NUL)
1457+ if (evaluate)
1458 {
1459- /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */
1460- if (key != NULL)
1461- EMSG(_(e_emptykey));
1462- clear_tv(&tvkey);
1463- goto failret;
1464+ key = get_tv_string_buf_chk(&tvkey, buf);
1465+ if (key == NULL || *key == NUL)
1466+ {
1467+ /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */
1468+ if (key != NULL)
1469+ EMSG(_(e_emptykey));
1470+ clear_tv(&tvkey);
1471+ goto failret;
1472+ }
1473 }
1474
1475 *arg = skipwhite(*arg + 1);
1476 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */
1477 {
1478- clear_tv(&tvkey);
1479+ if (evaluate)
1480+ clear_tv(&tvkey);
1481 goto failret;
1482 }
1483 if (evaluate)
1484@@ -6794,7 +6822,7 @@
[ba61c16]1485 * "numbuf" is used for a number.
1486 * Does not put quotes around strings, as ":echo" displays values.
1487 * When "copyID" is not NULL replace recursive lists and dicts with "...".
1488- * May return NULL;
1489+ * May return NULL.
1490 */
1491 static char_u *
1492 echo_string(tv, tofree, numbuf, copyID)
[c2aa910]1493@@ -6879,7 +6907,7 @@
[ba61c16]1494 * If the memory is allocated "tofree" is set to it, otherwise NULL.
1495 * "numbuf" is used for a number.
1496 * Puts quotes around strings, so that they can be parsed back by eval().
1497- * May return NULL;
1498+ * May return NULL.
1499 */
1500 static char_u *
1501 tv2string(tv, tofree, numbuf, copyID)
[c2aa910]1502@@ -7043,6 +7071,7 @@
[ba61c16]1503 {"changenr", 0, 0, f_changenr},
1504 {"char2nr", 1, 1, f_char2nr},
1505 {"cindent", 1, 1, f_cindent},
1506+ {"clearmatches", 0, 0, f_clearmatches},
1507 {"col", 1, 1, f_col},
1508 #if defined(FEAT_INS_EXPAND)
1509 {"complete", 2, 2, f_complete},
[c2aa910]1510@@ -7082,7 +7111,7 @@
1511 {"foldtextresult", 1, 1, f_foldtextresult},
1512 {"foreground", 0, 0, f_foreground},
1513 {"function", 1, 1, f_function},
1514- {"garbagecollect", 0, 0, f_garbagecollect},
1515+ {"garbagecollect", 0, 1, f_garbagecollect},
1516 {"get", 2, 3, f_get},
1517 {"getbufline", 2, 3, f_getbufline},
1518 {"getbufvar", 2, 2, f_getbufvar},
1519@@ -7099,6 +7128,7 @@
[ba61c16]1520 {"getftype", 1, 1, f_getftype},
1521 {"getline", 1, 2, f_getline},
1522 {"getloclist", 1, 1, f_getqflist},
1523+ {"getmatches", 0, 0, f_getmatches},
1524 {"getpos", 1, 1, f_getpos},
1525 {"getqflist", 0, 0, f_getqflist},
1526 {"getreg", 0, 2, f_getreg},
[c2aa910]1527@@ -7149,7 +7179,9 @@
[ba61c16]1528 {"maparg", 1, 3, f_maparg},
1529 {"mapcheck", 1, 3, f_mapcheck},
1530 {"match", 2, 4, f_match},
1531+ {"matchadd", 2, 4, f_matchadd},
1532 {"matcharg", 1, 1, f_matcharg},
1533+ {"matchdelete", 1, 1, f_matchdelete},
1534 {"matchend", 2, 4, f_matchend},
1535 {"matchlist", 2, 4, f_matchlist},
1536 {"matchstr", 2, 4, f_matchstr},
[c2aa910]1537@@ -7190,6 +7222,7 @@
[ba61c16]1538 {"setcmdpos", 1, 1, f_setcmdpos},
1539 {"setline", 2, 2, f_setline},
1540 {"setloclist", 2, 3, f_setloclist},
1541+ {"setmatches", 1, 1, f_setmatches},
1542 {"setpos", 2, 2, f_setpos},
1543 {"setqflist", 1, 2, f_setqflist},
1544 {"setreg", 2, 3, f_setreg},
[c2aa910]1545@@ -8240,6 +8273,20 @@
[ba61c16]1546 }
1547
1548 /*
1549+ * "clearmatches()" function
1550+ */
1551+/*ARGSUSED*/
1552+ static void
1553+f_clearmatches(argvars, rettv)
1554+ typval_T *argvars;
1555+ typval_T *rettv;
1556+{
1557+#ifdef FEAT_SEARCH_EXTRA
1558+ clear_matches(curwin);
1559+#endif
1560+}
1561+
1562+/*
1563 * "col(string)" function
1564 */
1565 static void
[c2aa910]1566@@ -9339,15 +9386,16 @@
1567 {
1568 typval_T rettv;
1569 char_u *s;
1570+ int retval = FAIL;
1571
1572 copy_tv(tv, &vimvars[VV_VAL].vv_tv);
1573 s = expr;
1574 if (eval1(&s, &rettv, TRUE) == FAIL)
1575- return FAIL;
1576+ goto theend;
1577 if (*s != NUL) /* check for trailing chars after expr */
1578 {
1579 EMSG2(_(e_invexpr2), s);
1580- return FAIL;
1581+ goto theend;
1582 }
1583 if (map)
1584 {
1585@@ -9366,10 +9414,12 @@
1586 /* On type error, nothing has been removed; return FAIL to stop the
1587 * loop. The error message was given by get_tv_number_chk(). */
1588 if (error)
1589- return FAIL;
1590+ goto theend;
1591 }
1592+ retval = OK;
1593+theend:
1594 clear_tv(&vimvars[VV_VAL].vv_tv);
1595- return OK;
1596+ return retval;
1597 }
1598
1599 /*
1600@@ -9670,6 +9720,9 @@
1601 /* This is postponed until we are back at the toplevel, because we may be
1602 * using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". */
1603 want_garbage_collect = TRUE;
1604+
1605+ if (argvars[0].v_type != VAR_UNKNOWN && get_tv_number(&argvars[0]) == 1)
1606+ garbage_collect_at_exit = TRUE;
1607 }
1608
1609 /*
1610@@ -9868,18 +9921,24 @@
1611
1612 ++no_mapping;
1613 ++allow_keys;
1614- if (argvars[0].v_type == VAR_UNKNOWN)
1615- /* getchar(): blocking wait. */
1616- n = safe_vgetc();
1617- else if (get_tv_number_chk(&argvars[0], &error) == 1)
1618- /* getchar(1): only check if char avail */
1619- n = vpeekc();
1620- else if (error || vpeekc() == NUL)
1621- /* illegal argument or getchar(0) and no char avail: return zero */
1622- n = 0;
1623- else
1624- /* getchar(0) and char avail: return char */
1625- n = safe_vgetc();
1626+ for (;;)
1627+ {
1628+ if (argvars[0].v_type == VAR_UNKNOWN)
1629+ /* getchar(): blocking wait. */
1630+ n = safe_vgetc();
1631+ else if (get_tv_number_chk(&argvars[0], &error) == 1)
1632+ /* getchar(1): only check if char avail */
1633+ n = vpeekc();
1634+ else if (error || vpeekc() == NUL)
1635+ /* illegal argument or getchar(0) and no char avail: return zero */
1636+ n = 0;
1637+ else
1638+ /* getchar(0) and char avail: return char */
1639+ n = safe_vgetc();
1640+ if (n == K_IGNORE)
1641+ continue;
1642+ break;
1643+ }
1644 --no_mapping;
1645 --allow_keys;
1646
1647@@ -10136,7 +10195,13 @@
[ba61c16]1648 if (mch_isdir(fname))
1649 rettv->vval.v_number = 0;
1650 else
1651+ {
1652 rettv->vval.v_number = (varnumber_T)st.st_size;
1653+
1654+ /* non-perfect check for overflow */
1655+ if ((off_t)rettv->vval.v_number != (off_t)st.st_size)
1656+ rettv->vval.v_number = -2;
1657+ }
1658 }
1659 else
1660 rettv->vval.v_number = -1;
[c2aa910]1661@@ -10269,6 +10334,39 @@
[ba61c16]1662 }
1663
1664 /*
1665+ * "getmatches()" function
1666+ */
1667+/*ARGSUSED*/
1668+ static void
1669+f_getmatches(argvars, rettv)
1670+ typval_T *argvars;
1671+ typval_T *rettv;
1672+{
1673+#ifdef FEAT_SEARCH_EXTRA
1674+ dict_T *dict;
1675+ matchitem_T *cur = curwin->w_match_head;
1676+
1677+ rettv->vval.v_number = 0;
1678+
1679+ if (rettv_list_alloc(rettv) == OK)
1680+ {
1681+ while (cur != NULL)
1682+ {
1683+ dict = dict_alloc();
1684+ if (dict == NULL)
1685+ return;
1686+ dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id));
1687+ dict_add_nr_str(dict, "pattern", 0L, cur->pattern);
1688+ dict_add_nr_str(dict, "priority", (long)cur->priority, NULL);
1689+ dict_add_nr_str(dict, "id", (long)cur->id, NULL);
1690+ list_append_dict(rettv->vval.v_list, dict);
1691+ cur = cur->next;
1692+ }
1693+ }
1694+#endif
1695+}
1696+
1697+/*
1698 * "getpos(string)" function
1699 */
1700 static void
[c2aa910]1701@@ -10290,7 +10388,8 @@
1702 list_append_number(l, (varnumber_T)0);
1703 list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum
1704 : (varnumber_T)0);
1705- list_append_number(l, (fp != NULL) ? (varnumber_T)fp->col + 1
1706+ list_append_number(l, (fp != NULL)
1707+ ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1)
1708 : (varnumber_T)0);
1709 list_append_number(l,
1710 #ifdef FEAT_VIRTUALEDIT
1711@@ -10785,6 +10884,9 @@
1712 "gui_gtk2",
1713 # endif
1714 #endif
1715+#ifdef FEAT_GUI_GNOME
1716+ "gui_gnome",
1717+#endif
1718 #ifdef FEAT_GUI_MAC
1719 "gui_mac",
1720 #endif
1721@@ -11471,14 +11573,12 @@
1722 char_u *xp_arg = NULL;
1723
1724 rettv->v_type = VAR_STRING;
1725+ rettv->vval.v_string = NULL;
1726
1727 #ifdef NO_CONSOLE_INPUT
1728 /* While starting up, there is no place to enter text. */
1729 if (no_console_input())
1730- {
1731- rettv->vval.v_string = NULL;
1732 return;
1733- }
1734 #endif
1735
1736 cmd_silent = FALSE; /* Want to see the prompt. */
1737@@ -12439,6 +12539,44 @@
[ba61c16]1738 }
1739
1740 /*
1741+ * "matchadd()" function
1742+ */
1743+ static void
1744+f_matchadd(argvars, rettv)
1745+ typval_T *argvars;
1746+ typval_T *rettv;
1747+{
1748+#ifdef FEAT_SEARCH_EXTRA
1749+ char_u buf[NUMBUFLEN];
1750+ char_u *grp = get_tv_string_buf_chk(&argvars[0], buf); /* group */
1751+ char_u *pat = get_tv_string_buf_chk(&argvars[1], buf); /* pattern */
1752+ int prio = 10; /* default priority */
1753+ int id = -1;
1754+ int error = FALSE;
1755+
1756+ rettv->vval.v_number = -1;
1757+
1758+ if (grp == NULL || pat == NULL)
1759+ return;
1760+ if (argvars[2].v_type != VAR_UNKNOWN)
1761+ {
1762+ prio = get_tv_number_chk(&argvars[2], &error);
1763+ if (argvars[3].v_type != VAR_UNKNOWN)
1764+ id = get_tv_number_chk(&argvars[3], &error);
1765+ }
1766+ if (error == TRUE)
1767+ return;
1768+ if (id >= 1 && id <= 3)
1769+ {
1770+ EMSGN("E798: ID is reserved for \":match\": %ld", id);
1771+ return;
1772+ }
1773+
1774+ rettv->vval.v_number = match_add(curwin, grp, pat, prio, id);
1775+#endif
1776+}
1777+
1778+/*
1779 * "matcharg()" function
1780 */
1781 static void
[c2aa910]1782@@ -12449,20 +12587,42 @@
[ba61c16]1783 if (rettv_list_alloc(rettv) == OK)
1784 {
1785 #ifdef FEAT_SEARCH_EXTRA
1786- int mi = get_tv_number(&argvars[0]);
1787+ int id = get_tv_number(&argvars[0]);
1788+ matchitem_T *m;
1789
1790- if (mi >= 1 && mi <= 3)
1791+ if (id >= 1 && id <= 3)
1792 {
1793- list_append_string(rettv->vval.v_list,
1794- syn_id2name(curwin->w_match_id[mi - 1]), -1);
1795- list_append_string(rettv->vval.v_list,
1796- curwin->w_match_pat[mi - 1], -1);
1797+ if ((m = (matchitem_T *)get_match(curwin, id)) != NULL)
1798+ {
1799+ list_append_string(rettv->vval.v_list,
1800+ syn_id2name(m->hlg_id), -1);
1801+ list_append_string(rettv->vval.v_list, m->pattern, -1);
1802+ }
1803+ else
1804+ {
1805+ list_append_string(rettv->vval.v_list, NUL, -1);
1806+ list_append_string(rettv->vval.v_list, NUL, -1);
1807+ }
1808 }
1809 #endif
1810 }
1811 }
1812
1813 /*
1814+ * "matchdelete()" function
1815+ */
1816+ static void
1817+f_matchdelete(argvars, rettv)
1818+ typval_T *argvars;
1819+ typval_T *rettv;
1820+{
1821+#ifdef FEAT_SEARCH_EXTRA
1822+ rettv->vval.v_number = match_delete(curwin,
1823+ (int)get_tv_number(&argvars[0]), TRUE);
1824+#endif
1825+}
1826+
1827+/*
1828 * "matchend()" function
1829 */
1830 static void
[c2aa910]1831@@ -13680,7 +13840,7 @@
[ba61c16]1832 }
1833 /* Shorten "remain". */
1834 if (*q != NUL)
1835- STRCPY(remain, q - 1);
1836+ mch_memmove(remain, q - 1, STRLEN(q - 1) + 1);
1837 else
1838 {
1839 vim_free(remain);
[c2aa910]1840@@ -13919,6 +14079,8 @@
[ba61c16]1841 /* If 'n' flag is used: restore cursor position. */
1842 if (flags & SP_NOMOVE)
1843 curwin->w_cursor = save_cursor;
1844+ else
1845+ curwin->w_set_curswant = TRUE;
1846 theend:
1847 p_ws = save_p_ws;
1848
[c2aa910]1849@@ -14498,6 +14660,66 @@
[ba61c16]1850 }
1851
1852 /*
1853+ * "setmatches()" function
1854+ */
1855+ static void
1856+f_setmatches(argvars, rettv)
1857+ typval_T *argvars;
1858+ typval_T *rettv;
1859+{
1860+#ifdef FEAT_SEARCH_EXTRA
1861+ list_T *l;
1862+ listitem_T *li;
1863+ dict_T *d;
1864+
1865+ rettv->vval.v_number = -1;
1866+ if (argvars[0].v_type != VAR_LIST)
1867+ {
1868+ EMSG(_(e_listreq));
1869+ return;
1870+ }
1871+ if ((l = argvars[0].vval.v_list) != NULL)
1872+ {
1873+
1874+ /* To some extent make sure that we are dealing with a list from
1875+ * "getmatches()". */
1876+ li = l->lv_first;
1877+ while (li != NULL)
1878+ {
1879+ if (li->li_tv.v_type != VAR_DICT
1880+ || (d = li->li_tv.vval.v_dict) == NULL)
1881+ {
1882+ EMSG(_(e_invarg));
1883+ return;
1884+ }
1885+ if (!(dict_find(d, (char_u *)"group", -1) != NULL
1886+ && dict_find(d, (char_u *)"pattern", -1) != NULL
1887+ && dict_find(d, (char_u *)"priority", -1) != NULL
1888+ && dict_find(d, (char_u *)"id", -1) != NULL))
1889+ {
1890+ EMSG(_(e_invarg));
1891+ return;
1892+ }
1893+ li = li->li_next;
1894+ }
1895+
1896+ clear_matches(curwin);
1897+ li = l->lv_first;
1898+ while (li != NULL)
1899+ {
1900+ d = li->li_tv.vval.v_dict;
1901+ match_add(curwin, get_dict_string(d, (char_u *)"group", FALSE),
1902+ get_dict_string(d, (char_u *)"pattern", FALSE),
1903+ (int)get_dict_number(d, (char_u *)"priority"),
1904+ (int)get_dict_number(d, (char_u *)"id"));
1905+ li = li->li_next;
1906+ }
1907+ rettv->vval.v_number = 0;
1908+ }
1909+#endif
1910+}
1911+
1912+/*
1913 * "setpos()" function
1914 */
1915 /*ARGSUSED*/
[c2aa910]1916@@ -14785,6 +15007,10 @@
[ba61c16]1917
1918 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1, 0);
1919 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2, 0);
1920+ if (p1 == NULL)
1921+ p1 = (char_u *)"";
1922+ if (p2 == NULL)
1923+ p2 = (char_u *)"";
1924 if (item_compare_ic)
1925 res = STRICMP(p1, p2);
1926 else
[c2aa910]1927@@ -15274,7 +15500,8 @@
[ba61c16]1928
1929 rettv->v_type = VAR_STRING;
1930 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0);
1931- if (tofree == NULL)
1932+ /* Make a copy if we have a value but it's not in allocate memory. */
1933+ if (rettv->vval.v_string != NULL && tofree == NULL)
1934 rettv->vval.v_string = vim_strsave(rettv->vval.v_string);
1935 }
1936
[c2aa910]1937@@ -16497,9 +16724,9 @@
[ba61c16]1938 * Returns NULL when there is an error.
1939 */
1940 static pos_T *
1941-var2fpos(varp, lnum, fnum)
1942+var2fpos(varp, dollar_lnum, fnum)
1943 typval_T *varp;
1944- int lnum; /* TRUE when $ is last line */
1945+ int dollar_lnum; /* TRUE when $ is last line */
1946 int *fnum; /* set to fnum for '0, 'A, etc. */
1947 {
1948 char_u *name;
[c2aa910]1949@@ -16512,6 +16739,7 @@
[ba61c16]1950 list_T *l;
1951 int len;
1952 int error = FALSE;
1953+ listitem_T *li;
1954
1955 l = varp->vval.v_list;
1956 if (l == NULL)
[c2aa910]1957@@ -16527,6 +16755,14 @@
[ba61c16]1958 if (error)
1959 return NULL;
1960 len = (long)STRLEN(ml_get(pos.lnum));
1961+
1962+ /* We accept "$" for the column number: last column. */
1963+ li = list_find(l, 1L);
1964+ if (li != NULL && li->li_tv.v_type == VAR_STRING
1965+ && li->li_tv.vval.v_string != NULL
1966+ && STRCMP(li->li_tv.vval.v_string, "$") == 0)
1967+ pos.col = len + 1;
1968+
1969 /* Accept a position up to the NUL after the line. */
1970 if (pos.col == 0 || (int)pos.col > len + 1)
1971 return NULL; /* invalid column number */
[c2aa910]1972@@ -16559,7 +16795,7 @@
[ba61c16]1973 pos.coladd = 0;
1974 #endif
1975
1976- if (name[0] == 'w' && lnum)
1977+ if (name[0] == 'w' && dollar_lnum)
1978 {
1979 pos.col = 0;
1980 if (name[1] == '0') /* "w0": first visible line */
[c2aa910]1981@@ -16577,7 +16813,7 @@
[ba61c16]1982 }
1983 else if (name[0] == '$') /* last column or line */
1984 {
1985- if (lnum)
1986+ if (dollar_lnum)
1987 {
1988 pos.lnum = curbuf->b_ml.ml_line_count;
1989 pos.col = 0;
[c2aa910]1990@@ -17798,9 +18034,10 @@
[ba61c16]1991 * List the value of one internal variable.
1992 */
1993 static void
1994-list_one_var(v, prefix)
1995+list_one_var(v, prefix, first)
1996 dictitem_T *v;
1997 char_u *prefix;
1998+ int *first;
1999 {
2000 char_u *tofree;
2001 char_u *s;
[c2aa910]2002@@ -17808,18 +18045,21 @@
[ba61c16]2003
2004 s = echo_string(&v->di_tv, &tofree, numbuf, ++current_copyID);
2005 list_one_var_a(prefix, v->di_key, v->di_tv.v_type,
2006- s == NULL ? (char_u *)"" : s);
2007+ s == NULL ? (char_u *)"" : s, first);
2008 vim_free(tofree);
2009 }
2010
2011 static void
2012-list_one_var_a(prefix, name, type, string)
2013+list_one_var_a(prefix, name, type, string, first)
2014 char_u *prefix;
2015 char_u *name;
2016 int type;
2017 char_u *string;
2018+ int *first; /* when TRUE clear rest of screen and set to FALSE */
2019 {
2020- msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */
2021+ /* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */
2022+ msg_start();
2023+ msg_puts(prefix);
2024 if (name != NULL) /* "a:" vars don't have a name stored */
2025 msg_puts(name);
2026 msg_putchar(' ');
[c2aa910]2027@@ -17847,6 +18087,11 @@
[ba61c16]2028
2029 if (type == VAR_FUNC)
2030 msg_puts((char_u *)"()");
2031+ if (*first)
2032+ {
2033+ msg_clr_eos();
2034+ *first = FALSE;
2035+ }
2036 }
2037
2038 /*
[c2aa910]2039@@ -19136,6 +19381,28 @@
2040 goto theend;
2041 }
2042
2043+ /* Check if the name is a Funcref. If so, use the value. */
2044+ if (lv.ll_exp_name != NULL)
2045+ {
2046+ len = (int)STRLEN(lv.ll_exp_name);
2047+ name = deref_func_name(lv.ll_exp_name, &len);
2048+ if (name == lv.ll_exp_name)
2049+ name = NULL;
2050+ }
2051+ else
2052+ {
2053+ len = (int)(end - *pp);
2054+ name = deref_func_name(*pp, &len);
2055+ if (name == *pp)
2056+ name = NULL;
2057+ }
2058+ if (name != NULL)
2059+ {
2060+ name = vim_strsave(name);
2061+ *pp = end;
2062+ goto theend;
2063+ }
2064+
2065 if (lv.ll_exp_name != NULL)
2066 {
2067 len = (int)STRLEN(lv.ll_exp_name);
2068@@ -19969,6 +20236,7 @@
[ba61c16]2069 char_u buf[MSG_BUF_LEN];
2070 char_u numbuf2[NUMBUFLEN];
2071 char_u *tofree;
2072+ char_u *s;
2073
2074 msg_puts((char_u *)"(");
2075 for (i = 0; i < argcount; ++i)
[c2aa910]2076@@ -19979,10 +20247,13 @@
[ba61c16]2077 msg_outnum((long)argvars[i].vval.v_number);
2078 else
2079 {
2080- trunc_string(tv2string(&argvars[i], &tofree,
2081- numbuf2, 0), buf, MSG_BUF_CLEN);
2082- msg_puts(buf);
2083- vim_free(tofree);
2084+ s = tv2string(&argvars[i], &tofree, numbuf2, 0);
2085+ if (s != NULL)
2086+ {
2087+ trunc_string(s, buf, MSG_BUF_CLEN);
2088+ msg_puts(buf);
2089+ vim_free(tofree);
2090+ }
2091 }
2092 }
2093 msg_puts((char_u *)")");
[c2aa910]2094@@ -20060,14 +20331,18 @@
[ba61c16]2095 char_u buf[MSG_BUF_LEN];
2096 char_u numbuf2[NUMBUFLEN];
2097 char_u *tofree;
2098+ char_u *s;
2099
2100 /* The value may be very long. Skip the middle part, so that we
2101 * have some idea how it starts and ends. smsg() would always
2102 * truncate it at the end. */
2103- trunc_string(tv2string(fc.rettv, &tofree, numbuf2, 0),
2104- buf, MSG_BUF_CLEN);
2105- smsg((char_u *)_("%s returning %s"), sourcing_name, buf);
2106- vim_free(tofree);
2107+ s = tv2string(fc.rettv, &tofree, numbuf2, 0);
2108+ if (s != NULL)
2109+ {
2110+ trunc_string(s, buf, MSG_BUF_CLEN);
2111+ smsg((char_u *)_("%s returning %s"), sourcing_name, buf);
2112+ vim_free(tofree);
2113+ }
2114 }
2115 msg_puts((char_u *)"\n"); /* don't overwrite this either */
2116
[c2aa910]2117@@ -21034,14 +21309,27 @@
2118 *usedlen += 2;
2119 s = get_past_head(*fnamep);
2120 while (tail > s && after_pathsep(s, tail))
2121- --tail;
2122+ mb_ptr_back(*fnamep, tail);
2123 *fnamelen = (int)(tail - *fnamep);
2124 #ifdef VMS
2125 if (*fnamelen > 0)
2126 *fnamelen += 1; /* the path separator is part of the path */
2127 #endif
2128- while (tail > s && !after_pathsep(s, tail))
2129- mb_ptr_back(*fnamep, tail);
2130+ if (*fnamelen == 0)
2131+ {
2132+ /* Result is empty. Turn it into "." to make ":cd %:h" work. */
2133+ p = vim_strsave((char_u *)".");
2134+ if (p == NULL)
2135+ return -1;
2136+ vim_free(*bufp);
2137+ *bufp = *fnamep = tail = p;
2138+ *fnamelen = 1;
2139+ }
2140+ else
2141+ {
2142+ while (tail > s && !after_pathsep(s, tail))
2143+ mb_ptr_back(*fnamep, tail);
2144+ }
2145 }
2146
2147 /* ":8" - shortname */
[ba61c16]2148diff -Naur vim71.orig/src/ex_cmds.c vim71/src/ex_cmds.c
2149--- vim71.orig/src/ex_cmds.c 2007-05-07 12:41:01.000000000 -0700
[c2aa910]2150+++ vim71/src/ex_cmds.c 2007-10-16 14:14:28.000000000 -0700
[ba61c16]2151@@ -408,7 +408,11 @@
2152 goto sortend;
2153 }
2154 *s = NUL;
2155- regmatch.regprog = vim_regcomp(p + 1, RE_MAGIC);
2156+ /* Use last search pattern if sort pattern is empty. */
2157+ if (s == p + 1 && last_search_pat() != NULL)
2158+ regmatch.regprog = vim_regcomp(last_search_pat(), RE_MAGIC);
2159+ else
2160+ regmatch.regprog = vim_regcomp(p + 1, RE_MAGIC);
2161 if (regmatch.regprog == NULL)
2162 goto sortend;
2163 p = s; /* continue after the regexp */
2164@@ -2912,22 +2916,35 @@
2165 }
2166
2167 /*
2168- * Check if a buffer is read-only. Ask for overruling in a dialog.
2169- * Return TRUE and give an error message when the buffer is readonly.
2170+ * Check if a buffer is read-only (either 'readonly' option is set or file is
2171+ * read-only). Ask for overruling in a dialog. Return TRUE and give an error
2172+ * message when the buffer is readonly.
2173 */
2174 static int
2175 check_readonly(forceit, buf)
2176 int *forceit;
2177 buf_T *buf;
2178 {
2179- if (!*forceit && buf->b_p_ro)
2180+ struct stat st;
2181+
2182+ /* Handle a file being readonly when the 'readonly' option is set or when
2183+ * the file exists and permissions are read-only.
2184+ * We will send 0777 to check_file_readonly(), as the "perm" variable is
2185+ * important for device checks but not here. */
2186+ if (!*forceit && (buf->b_p_ro
2187+ || (mch_stat((char *)buf->b_ffname, &st) >= 0
2188+ && check_file_readonly(buf->b_ffname, 0777))))
2189 {
2190 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
2191 if ((p_confirm || cmdmod.confirm) && buf->b_fname != NULL)
2192 {
2193 char_u buff[IOSIZE];
2194
2195- dialog_msg(buff, _("'readonly' option is set for \"%s\".\nDo you wish to write anyway?"),
2196+ if (buf->b_p_ro)
2197+ dialog_msg(buff, _("'readonly' option is set for \"%s\".\nDo you wish to write anyway?"),
2198+ buf->b_fname);
2199+ else
2200+ dialog_msg(buff, _("File permissions of \"%s\" are read-only.\nIt may still be possible to write it.\nDo you wish to try?"),
2201 buf->b_fname);
2202
2203 if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) == VIM_YES)
2204@@ -2941,9 +2958,14 @@
2205 }
2206 else
2207 #endif
2208+ if (buf->b_p_ro)
2209 EMSG(_(e_readonly));
2210+ else
2211+ EMSG2(_("E505: \"%s\" is read-only (add ! to override)"),
2212+ buf->b_fname);
2213 return TRUE;
2214 }
2215+
2216 return FALSE;
2217 }
2218
2219@@ -2952,7 +2974,7 @@
2220 * 'fnum' is the number of the file, if zero use ffname/sfname.
2221 *
2222 * Return 1 for "normal" error, 2 for "not written" error, 0 for success
2223- * -1 for succesfully opening another file.
2224+ * -1 for successfully opening another file.
2225 * 'lnum' is the line number for the cursor in the new file (if non-zero).
2226 */
2227 int
2228@@ -3367,7 +3389,7 @@
2229 * was in this window (or another window). If not used
2230 * before, reset the local window options to the global
2231 * values. Also restores old folding stuff. */
2232- get_winopts(buf);
2233+ get_winopts(curbuf);
2234 #ifdef FEAT_SPELL
2235 did_get_winopts = TRUE;
2236 #endif
2237@@ -3562,9 +3584,20 @@
2238 curwin_init();
2239
2240 #ifdef FEAT_FOLDING
2241- /* It's like all lines in the buffer changed. Need to update
2242- * automatic folding. */
2243+ /* It's possible that all lines in the buffer changed. Need to update
2244+ * automatic folding for all windows where it's used. */
2245+# ifdef FEAT_WINDOWS
2246+ {
2247+ win_T *win;
2248+ tabpage_T *tp;
2249+
2250+ FOR_ALL_TAB_WINDOWS(tp, win)
2251+ if (win->w_buffer == curbuf)
2252+ foldUpdateAll(win);
2253+ }
2254+# else
2255 foldUpdateAll(curwin);
2256+# endif
2257 #endif
2258
2259 /* Change directories when the 'acd' option is set. */
2260@@ -3649,8 +3682,8 @@
2261 #ifdef FEAT_SPELL
2262 /* If the window options were changed may need to set the spell language.
2263 * Can only do this after the buffer has been properly setup. */
2264- if (did_get_winopts && curwin->w_p_spell && *buf->b_p_spl != NUL)
2265- did_set_spelllang(buf);
2266+ if (did_get_winopts && curwin->w_p_spell && *curbuf->b_p_spl != NUL)
2267+ did_set_spelllang(curbuf);
2268 #endif
2269
2270 if (command == NULL)
2271@@ -3754,7 +3787,7 @@
2272 workshop_file_opened((char *)curbuf->b_ffname, curbuf->b_p_ro);
2273 # endif
2274 # ifdef FEAT_NETBEANS_INTG
2275- if (usingNetbeans & ((flags & ECMD_SET_HELP) != ECMD_SET_HELP))
2276+ if (usingNetbeans && ((flags & ECMD_SET_HELP) != ECMD_SET_HELP))
2277 netbeans_file_opened(curbuf);
2278 # endif
2279 }
2280@@ -4294,6 +4327,7 @@
2281 do_error = TRUE;
2282 do_print = FALSE;
2283 do_count = FALSE;
2284+ do_number = FALSE;
2285 do_ic = 0;
2286 }
2287 while (*cmd)
[c2aa910]2288@@ -4464,7 +4498,7 @@
2289 *
2290 * The new text is built up in new_start[]. It has some extra
2291 * room to avoid using alloc()/free() too often. new_start_len is
2292- * the lenght of the allocated memory at new_start.
2293+ * the length of the allocated memory at new_start.
2294 *
2295 * Make a copy of the old line, so it won't be taken away when
2296 * updating the screen or handling a multi-line match. The "old_"
2297@@ -4635,7 +4669,7 @@
2298 #endif
2299 ++no_mapping; /* don't map this key */
2300 ++allow_keys; /* allow special keys */
2301- i = safe_vgetc();
2302+ i = plain_vgetc();
2303 --allow_keys;
2304 --no_mapping;
2305
[ba61c16]2306@@ -6351,9 +6385,9 @@
2307 for (i = 0; i < ga.ga_len; ++i)
2308 {
2309 s = ((char_u **)ga.ga_data)[i];
2310- if (STRNCMP(s, "help-tags", 9) == 0)
2311+ if (STRNCMP(s, "help-tags\t", 10) == 0)
2312 /* help-tags entry was added in formatted form */
2313- fprintf(fd_tags, (char *)s);
2314+ fputs((char *)s, fd_tags);
2315 else
2316 {
2317 fprintf(fd_tags, "%s\t/*", s);
2318diff -Naur vim71.orig/src/ex_docmd.c vim71/src/ex_docmd.c
2319--- vim71.orig/src/ex_docmd.c 2007-05-07 12:49:38.000000000 -0700
[c2aa910]2320+++ vim71/src/ex_docmd.c 2007-10-16 14:14:28.000000000 -0700
[ba61c16]2321@@ -133,6 +133,7 @@
2322 static void get_flags __ARGS((exarg_T *eap));
2323 #if !defined(FEAT_PERL) || !defined(FEAT_PYTHON) || !defined(FEAT_TCL) \
2324 || !defined(FEAT_RUBY) || !defined(FEAT_MZSCHEME)
2325+# define HAVE_EX_SCRIPT_NI
2326 static void ex_script_ni __ARGS((exarg_T *eap));
2327 #endif
2328 static char_u *invalid_range __ARGS((exarg_T *eap));
2329@@ -2118,7 +2119,11 @@
2330 #ifdef FEAT_USR_CMDS
2331 !USER_CMDIDX(ea.cmdidx) &&
2332 #endif
2333- cmdnames[ea.cmdidx].cmd_func == ex_ni);
2334+ (cmdnames[ea.cmdidx].cmd_func == ex_ni
2335+#ifdef HAVE_EX_SCRIPT_NI
2336+ || cmdnames[ea.cmdidx].cmd_func == ex_script_ni
2337+#endif
2338+ ));
2339
2340 #ifndef FEAT_EVAL
2341 /*
2342@@ -3276,39 +3281,65 @@
2343
2344 if (ea.argt & XFILE)
2345 {
2346- int in_quote = FALSE;
2347- char_u *bow = NULL; /* Beginning of word */
2348+ int c;
2349+ int in_quote = FALSE;
2350+ char_u *bow = NULL; /* Beginning of word */
2351
2352 /*
2353 * Allow spaces within back-quotes to count as part of the argument
2354 * being expanded.
2355 */
2356 xp->xp_pattern = skipwhite(arg);
2357- for (p = xp->xp_pattern; *p; )
2358+ p = xp->xp_pattern;
2359+ while (*p != NUL)
2360 {
2361- if (*p == '\\' && p[1] != NUL)
2362+#ifdef FEAT_MBYTE
2363+ if (has_mbyte)
2364+ c = mb_ptr2char(p);
2365+ else
2366+#endif
2367+ c = *p;
2368+ if (c == '\\' && p[1] != NUL)
2369 ++p;
2370+ else if (c == '`')
2371+ {
2372+ if (!in_quote)
2373+ {
2374+ xp->xp_pattern = p;
2375+ bow = p + 1;
2376+ }
2377+ in_quote = !in_quote;
2378+ }
2379 #ifdef SPACE_IN_FILENAME
2380- else if (vim_iswhite(*p) && (!(ea.argt & NOSPC) || usefilter))
2381+ else if (!vim_isfilec_or_wc(c)
2382+ && (!(ea.argt & NOSPC) || usefilter))
2383 #else
2384- else if (vim_iswhite(*p))
2385+ else if (!vim_isfilec_or_wc(c))
2386 #endif
2387 {
2388- p = skipwhite(p);
2389+ while (*p != NUL)
2390+ {
2391+#ifdef FEAT_MBYTE
2392+ if (has_mbyte)
2393+ c = mb_ptr2char(p);
2394+ else
2395+#endif
2396+ c = *p;
2397+ if (c == '`' || vim_isfilec_or_wc(c))
2398+ break;
2399+#ifdef FEAT_MBYTE
2400+ if (has_mbyte)
2401+ len = (*mb_ptr2len)(p);
2402+ else
2403+#endif
2404+ len = 1;
2405+ mb_ptr_adv(p);
2406+ }
2407 if (in_quote)
2408 bow = p;
2409 else
2410 xp->xp_pattern = p;
2411- --p;
2412- }
2413- else if (*p == '`')
2414- {
2415- if (!in_quote)
2416- {
2417- xp->xp_pattern = p;
2418- bow = p + 1;
2419- }
2420- in_quote = !in_quote;
2421+ p -= len;
2422 }
2423 mb_ptr_adv(p);
2424 }
2425@@ -3401,14 +3432,13 @@
2426 case CMD_windo:
2427 return arg;
2428
2429-#ifdef FEAT_SEARCH_EXTRA
2430+#ifdef FEAT_CMDL_COMPL
2431+# ifdef FEAT_SEARCH_EXTRA
2432 case CMD_match:
2433 if (*arg == NUL || !ends_excmd(*arg))
2434 {
2435- /* Dummy call to clear variables. */
2436- set_context_in_highlight_cmd(xp, (char_u *)"link n");
2437- xp->xp_context = EXPAND_HIGHLIGHT;
2438- xp->xp_pattern = arg;
2439+ /* also complete "None" */
2440+ set_context_in_echohl_cmd(xp, arg);
2441 arg = skipwhite(skiptowhite(arg));
2442 if (*arg != NUL)
2443 {
2444@@ -3417,9 +3447,8 @@
2445 }
2446 }
2447 return find_nextcmd(arg);
2448-#endif
2449+# endif
2450
2451-#ifdef FEAT_CMDL_COMPL
2452 /*
2453 * All completion for the +cmdline_compl feature goes here.
2454 */
2455@@ -3617,8 +3646,7 @@
2456 break;
2457
2458 case CMD_echohl:
2459- xp->xp_context = EXPAND_HIGHLIGHT;
2460- xp->xp_pattern = arg;
2461+ set_context_in_echohl_cmd(xp, arg);
2462 break;
2463 #endif
2464 case CMD_highlight:
2465@@ -3997,8 +4025,7 @@
2466 eap->errmsg = (char_u *)N_("E319: Sorry, the command is not available in this version");
2467 }
2468
2469-#if !defined(FEAT_PERL) || !defined(FEAT_PYTHON) || !defined(FEAT_TCL) \
2470- || !defined(FEAT_RUBY) || !defined(FEAT_MZSCHEME)
2471+#ifdef HAVE_EX_SCRIPT_NI
2472 /*
2473 * Function called for script command which is Not Implemented. NI!
2474 * Skips over ":perl <<EOF" constructs.
[c2aa910]2475@@ -4376,7 +4403,7 @@
2476 || vim_strchr(eap->arg, '~') != NULL)
2477 {
2478 expand_env_esc(eap->arg, NameBuff, MAXPATHL,
2479- TRUE, NULL);
2480+ TRUE, TRUE, NULL);
2481 has_wildcards = mch_has_wildcard(NameBuff);
2482 p = NameBuff;
2483 }
[ba61c16]2484@@ -4492,7 +4519,8 @@
2485 if (eap->argt & (USECTRLV | XFILE))
2486 ++p; /* skip CTRL-V and next char */
2487 else
2488- STRCPY(p, p + 1); /* remove CTRL-V and skip next char */
2489+ /* remove CTRL-V and skip next char */
2490+ mch_memmove(p, p + 1, STRLEN(p));
2491 if (*p == NUL) /* stop at NUL after CTRL-V */
2492 break;
2493 }
2494@@ -10816,12 +10844,13 @@
2495 exarg_T *eap;
2496 {
2497 char_u *p;
2498+ char_u *g = NULL;
2499 char_u *end;
2500 int c;
2501- int mi;
2502+ int id;
2503
2504 if (eap->line2 <= 3)
2505- mi = eap->line2 - 1;
2506+ id = eap->line2;
2507 else
2508 {
2509 EMSG(e_invcmd);
2510@@ -10830,13 +10859,7 @@
2511
2512 /* First clear any old pattern. */
2513 if (!eap->skip)
2514- {
2515- vim_free(curwin->w_match[mi].regprog);
2516- curwin->w_match[mi].regprog = NULL;
2517- vim_free(curwin->w_match_pat[mi]);
2518- curwin->w_match_pat[mi] = NULL;
2519- redraw_later(SOME_VALID); /* always need a redraw */
2520- }
2521+ match_delete(curwin, id, FALSE);
2522
2523 if (ends_excmd(*eap->arg))
2524 end = eap->arg;
2525@@ -10847,15 +10870,7 @@
2526 {
2527 p = skiptowhite(eap->arg);
2528 if (!eap->skip)
2529- {
2530- curwin->w_match_id[mi] = syn_namen2id(eap->arg,
2531- (int)(p - eap->arg));
2532- if (curwin->w_match_id[mi] == 0)
2533- {
2534- EMSG2(_(e_nogroup), eap->arg);
2535- return;
2536- }
2537- }
2538+ g = vim_strnsave(eap->arg, (int)(p - eap->arg));
2539 p = skipwhite(p);
2540 if (*p == NUL)
2541 {
2542@@ -10879,14 +10894,8 @@
2543
2544 c = *end;
2545 *end = NUL;
2546- curwin->w_match[mi].regprog = vim_regcomp(p + 1, RE_MAGIC);
2547- if (curwin->w_match[mi].regprog == NULL)
2548- {
2549- EMSG2(_(e_invarg2), p);
2550- *end = c;
2551- return;
2552- }
2553- curwin->w_match_pat[mi] = vim_strsave(p + 1);
2554+ match_add(curwin, g, p + 1, 10, id);
2555+ vim_free(g);
2556 *end = c;
2557 }
2558 }
2559diff -Naur vim71.orig/src/ex_eval.c vim71/src/ex_eval.c
2560--- vim71.orig/src/ex_eval.c 2007-05-07 12:47:50.000000000 -0700
[c2aa910]2561+++ vim71/src/ex_eval.c 2007-10-16 14:14:09.000000000 -0700
[ba61c16]2562@@ -1551,7 +1551,7 @@
2563 }
2564 save_cpo = p_cpo;
2565 p_cpo = (char_u *)"";
2566- regmatch.regprog = vim_regcomp(pat, TRUE);
2567+ regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
2568 regmatch.rm_ic = FALSE;
2569 if (end != NULL)
2570 *end = save_char;
2571diff -Naur vim71.orig/src/ex_getln.c vim71/src/ex_getln.c
2572--- vim71.orig/src/ex_getln.c 2007-05-07 12:47:23.000000000 -0700
[c2aa910]2573+++ vim71/src/ex_getln.c 2007-10-16 14:14:34.000000000 -0700
[ba61c16]2574@@ -268,7 +268,9 @@
2575 {
2576 xpc.xp_context = ccline.xp_context;
2577 xpc.xp_pattern = ccline.cmdbuff;
2578+# if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)
2579 xpc.xp_arg = ccline.xp_arg;
2580+# endif
2581 }
2582 #endif
2583
2584@@ -484,7 +486,8 @@
2585 if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu)
2586 {
2587 /* Hitting <Down> after "emenu Name.": complete submenu */
2588- if (ccline.cmdbuff[ccline.cmdpos - 1] == '.' && c == K_DOWN)
2589+ if (c == K_DOWN && ccline.cmdpos > 0
2590+ && ccline.cmdbuff[ccline.cmdpos - 1] == '.')
2591 c = p_wc;
2592 else if (c == K_UP)
2593 {
2594@@ -533,9 +536,11 @@
2595 upseg[3] = PATHSEP;
2596 upseg[4] = NUL;
2597
2598- if (ccline.cmdbuff[ccline.cmdpos - 1] == PATHSEP
2599- && c == K_DOWN
2600- && (ccline.cmdbuff[ccline.cmdpos - 2] != '.'
2601+ if (c == K_DOWN
2602+ && ccline.cmdpos > 0
2603+ && ccline.cmdbuff[ccline.cmdpos - 1] == PATHSEP
2604+ && (ccline.cmdpos < 3
2605+ || ccline.cmdbuff[ccline.cmdpos - 2] != '.'
2606 || ccline.cmdbuff[ccline.cmdpos - 3] != '.'))
2607 {
2608 /* go down a directory */
[c2aa910]2609@@ -636,7 +641,7 @@
2610 {
2611 ++no_mapping;
2612 ++allow_keys;
2613- c = safe_vgetc();
2614+ c = plain_vgetc();
2615 --no_mapping;
2616 --allow_keys;
2617 /* CTRL-\ e doesn't work when obtaining an expression. */
[ba61c16]2618@@ -730,8 +735,8 @@
2619 /* In Ex mode a backslash escapes a newline. */
2620 if (exmode_active
2621 && c != ESC
2622- && ccline.cmdpos > 0
2623 && ccline.cmdpos == ccline.cmdlen
2624+ && ccline.cmdpos > 0
2625 && ccline.cmdbuff[ccline.cmdpos - 1] == '\\')
2626 {
2627 if (c == K_KENTER)
[c2aa910]2628@@ -1086,11 +1091,11 @@
2629 #endif
2630 putcmdline('"', TRUE);
2631 ++no_mapping;
2632- i = c = safe_vgetc(); /* CTRL-R <char> */
2633+ i = c = plain_vgetc(); /* CTRL-R <char> */
2634 if (i == Ctrl_O)
2635 i = Ctrl_R; /* CTRL-R CTRL-O == CTRL-R CTRL-R */
2636 if (i == Ctrl_R)
2637- c = safe_vgetc(); /* CTRL-R CTRL-R <char> */
2638+ c = plain_vgetc(); /* CTRL-R CTRL-R <char> */
2639 --no_mapping;
2640 #ifdef FEAT_EVAL
2641 /*
[ba61c16]2642@@ -2090,11 +2095,11 @@
2643 garray_T line_ga;
2644 char_u *pend;
2645 int startcol = 0;
2646- int c1;
2647+ int c1 = 0;
2648 int escaped = FALSE; /* CTRL-V typed */
2649 int vcol = 0;
2650 char_u *p;
2651- int prev_char = 0;
2652+ int prev_char;
2653
2654 /* Switch cursor on now. This avoids that it happens after the "\n", which
2655 * confuses the system function that computes tabstops. */
2656@@ -2147,6 +2152,7 @@
2657
2658 /* Get one character at a time. Don't use inchar(), it can't handle
2659 * special characters. */
2660+ prev_char = c1;
2661 c1 = vgetc();
2662
2663 /*
2664@@ -2204,7 +2210,6 @@
2665 redraw:
2666 /* redraw the line */
2667 msg_col = startcol;
2668- windgoto(msg_row, msg_col);
2669 vcol = 0;
2670 for (p = (char_u *)line_ga.ga_data;
2671 p < (char_u *)line_ga.ga_data + line_ga.ga_len; ++p)
2672@@ -2223,6 +2228,7 @@
2673 }
2674 }
2675 msg_clr_eos();
2676+ windgoto(msg_row, msg_col);
2677 continue;
2678 }
2679
2680@@ -2268,7 +2274,6 @@
2681 if (IS_SPECIAL(c1))
2682 c1 = '?';
2683 ((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
2684- prev_char = c1;
2685 if (c1 == '\n')
2686 msg_putchar('\n');
2687 else if (c1 == TAB)
[c2aa910]2688@@ -3311,6 +3316,10 @@
2689 * Return a pointer to alloced memory containing the new string.
2690 * Return NULL for failure.
2691 *
2692+ * "orig" is the originally expanded string, copied to allocated memory. It
2693+ * should either be kept in orig_save or freed. When "mode" is WILD_NEXT or
2694+ * WILD_PREV "orig" should be NULL.
2695+ *
2696 * Results are cached in xp->xp_files and xp->xp_numfiles, except when "mode"
2697 * is WILD_EXPAND_FREE or WILD_ALL.
2698 *
2699@@ -3395,7 +3404,7 @@
2700 return NULL;
2701 }
2702
2703-/* free old names */
2704+ /* free old names */
2705 if (xp->xp_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST)
2706 {
2707 FreeWild(xp->xp_numfiles, xp->xp_files);
2708@@ -3536,6 +3545,10 @@
2709 if (mode == WILD_EXPAND_FREE || mode == WILD_ALL)
2710 ExpandCleanup(xp);
2711
2712+ /* Free "orig" if it wasn't stored in "orig_save". */
2713+ if (orig != orig_save)
2714+ vim_free(orig);
2715+
2716 return ss;
2717 }
2718
2719@@ -4148,13 +4161,19 @@
[ba61c16]2720
2721 #ifdef FEAT_EVAL
2722 if (ccline.cmdfirstc == '=')
2723+ {
2724+# ifdef FEAT_CMDL_COMPL
2725 /* pass CMD_SIZE because there is no real command */
2726 set_context_for_expression(xp, str, CMD_SIZE);
2727+# endif
2728+ }
2729 else if (ccline.input_fn)
2730 {
2731 xp->xp_context = ccline.xp_context;
2732 xp->xp_pattern = ccline.cmdbuff;
2733+# if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)
2734 xp->xp_arg = ccline.xp_arg;
2735+# endif
2736 }
2737 else
2738 #endif
[c2aa910]2739@@ -4295,10 +4314,11 @@
[ba61c16]2740 && pat[i + 1] == '\\'
2741 && pat[i + 2] == '\\'
2742 && pat[i + 3] == ' ')
2743- STRCPY(pat + i, pat + i + 3);
2744+ mch_memmove(pat + i, pat + i + 3,
2745+ STRLEN(pat + i + 3) + 1);
2746 if (xp->xp_backslash == XP_BS_ONE
2747 && pat[i + 1] == ' ')
2748- STRCPY(pat + i, pat + i + 1);
2749+ mch_memmove(pat + i, pat + i + 1, STRLEN(pat + i));
2750 }
2751 }
2752
[c2aa910]2753@@ -4502,6 +4522,12 @@
[ba61c16]2754 if (xp->xp_context != EXPAND_MENUNAMES && xp->xp_context != EXPAND_MENUS)
2755 sort_strings(*file, *num_file);
2756
2757+#ifdef FEAT_CMDL_COMPL
2758+ /* Reset the variables used for special highlight names expansion, so that
2759+ * they don't show up when getting normal highlight names by ID. */
2760+ reset_expand_highlight();
2761+#endif
2762+
2763 return OK;
2764 }
2765
[c2aa910]2766@@ -4535,7 +4561,7 @@
[ba61c16]2767 pat = vim_strsave(filepat);
2768 for (i = 0; pat[i]; ++i)
2769 if (pat[i] == '\\' && pat[i + 1] == ' ')
2770- STRCPY(pat + i, pat + i + 1);
2771+ mch_memmove(pat + i, pat + i + 1, STRLEN(pat + i));
2772
2773 flags |= EW_FILE | EW_EXEC;
2774
[c2aa910]2775@@ -5907,7 +5933,7 @@
2776
2777 # ifdef FEAT_AUTOCMD
2778 /* Don't execute autocommands while creating the window. */
2779- ++autocmd_block;
2780+ block_autocmds();
2781 # endif
2782 /* don't use a new tab page */
2783 cmdmod.tab = 0;
2784@@ -5916,6 +5942,9 @@
2785 if (win_split((int)p_cwh, WSP_BOT) == FAIL)
2786 {
2787 beep_flush();
2788+# ifdef FEAT_AUTOCMD
2789+ unblock_autocmds();
2790+# endif
2791 return K_IGNORE;
2792 }
2793 cmdwin_type = ccline.cmdfirstc;
2794@@ -5938,7 +5967,7 @@
2795
2796 # ifdef FEAT_AUTOCMD
2797 /* Do execute autocommands for setting the filetype (load syntax). */
2798- --autocmd_block;
2799+ unblock_autocmds();
2800 # endif
2801
2802 /* Showing the prompt may have set need_wait_return, reset it. */
2803@@ -6092,7 +6121,7 @@
2804
2805 # ifdef FEAT_AUTOCMD
2806 /* Don't execute autocommands while deleting the window. */
2807- ++autocmd_block;
2808+ block_autocmds();
2809 # endif
2810 wp = curwin;
2811 bp = curbuf;
2812@@ -6104,7 +6133,7 @@
2813 win_size_restore(&winsizes);
2814
2815 # ifdef FEAT_AUTOCMD
2816- --autocmd_block;
2817+ unblock_autocmds();
2818 # endif
2819 }
2820
[ba61c16]2821diff -Naur vim71.orig/src/feature.h vim71/src/feature.h
2822--- vim71.orig/src/feature.h 2007-05-07 12:33:19.000000000 -0700
[c2aa910]2823+++ vim71/src/feature.h 2007-10-16 14:14:09.000000000 -0700
[ba61c16]2824@@ -673,7 +673,7 @@
2825 # define ESC_CHG_TO_ENG_MODE /* if defined, when ESC pressed,
2826 * turn to english mode
2827 */
2828-# if !defined(FEAT_XFONTSET) && defined(HAVE_X11)
2829+# if !defined(FEAT_XFONTSET) && defined(HAVE_X11) && !defined(HAVE_GTK2)
2830 # define FEAT_XFONTSET /* Hangul input requires xfontset */
2831 # endif
2832 # if defined(FEAT_XIM) && !defined(LINT)
2833diff -Naur vim71.orig/src/fileio.c vim71/src/fileio.c
2834--- vim71.orig/src/fileio.c 2007-05-10 04:29:44.000000000 -0700
[c2aa910]2835+++ vim71/src/fileio.c 2007-10-16 14:14:38.000000000 -0700
[ba61c16]2836@@ -44,6 +44,10 @@
2837 /* Is there any system that doesn't have access()? */
2838 #define USE_MCH_ACCESS
2839
2840+#if defined(sun) && defined(S_ISCHR)
2841+# define OPEN_CHR_FILES
2842+static int is_dev_fd_file(char_u *fname);
2843+#endif
2844 #ifdef FEAT_MBYTE
2845 static char_u *next_fenc __ARGS((char_u **pp));
2846 # ifdef FEAT_EVAL
2847@@ -406,6 +410,10 @@
2848 # ifdef S_ISSOCK
2849 && !S_ISSOCK(perm) /* ... or socket */
2850 # endif
2851+# ifdef OPEN_CHR_FILES
2852+ && !(S_ISCHR(perm) && is_dev_fd_file(fname))
2853+ /* ... or a character special file named /dev/fd/<n> */
2854+# endif
2855 )
2856 {
2857 if (S_ISDIR(perm))
2858@@ -424,7 +432,7 @@
2859 */
2860 if (!p_odev && mch_nodetype(fname) == NODE_WRITABLE)
2861 {
2862- filemess(curbuf, fname, (char_u *)_("is a device (disabled with 'opendevice' option"), 0);
2863+ filemess(curbuf, fname, (char_u *)_("is a device (disabled with 'opendevice' option)"), 0);
2864 msg_end();
2865 msg_scroll = msg_save;
2866 return FAIL;
2867@@ -646,6 +654,7 @@
2868 curbuf->b_start_eol = TRUE;
2869 #ifdef FEAT_MBYTE
2870 curbuf->b_p_bomb = FALSE;
2871+ curbuf->b_start_bomb = FALSE;
2872 #endif
2873 }
2874
2875@@ -904,7 +913,10 @@
2876 file_rewind = FALSE;
2877 #ifdef FEAT_MBYTE
2878 if (set_options)
2879+ {
2880 curbuf->b_p_bomb = FALSE;
2881+ curbuf->b_start_bomb = FALSE;
2882+ }
2883 conv_error = 0;
2884 #endif
2885 }
2886@@ -1353,7 +1365,10 @@
2887 size -= blen;
2888 mch_memmove(ptr, ptr + blen, (size_t)size);
2889 if (set_options)
2890+ {
2891 curbuf->b_p_bomb = TRUE;
2892+ curbuf->b_start_bomb = TRUE;
2893+ }
2894 }
2895
2896 if (fio_flags == FIO_UCSBOM)
2897@@ -2265,6 +2280,13 @@
2898 }
2899 # endif
2900 # endif
2901+# ifdef OPEN_CHR_FILES
2902+ if (S_ISCHR(perm)) /* or character special */
2903+ {
2904+ STRCAT(IObuff, _("[character special]"));
2905+ c = TRUE;
2906+ }
2907+# endif
2908 #endif
2909 if (curbuf->b_p_ro)
2910 {
2911@@ -2464,6 +2486,25 @@
2912 return OK;
2913 }
2914
2915+#ifdef OPEN_CHR_FILES
2916+/*
2917+ * Returns TRUE if the file name argument is of the form "/dev/fd/\d\+",
2918+ * which is the name of files used for process substitution output by
2919+ * some shells on some operating systems, e.g., bash on SunOS.
2920+ * Do not accept "/dev/fd/[012]", opening these may hang Vim.
2921+ */
2922+ static int
2923+is_dev_fd_file(fname)
2924+ char_u *fname;
2925+{
2926+ return (STRNCMP(fname, "/dev/fd/", 8) == 0
2927+ && VIM_ISDIGIT(fname[8])
2928+ && *skipdigits(fname + 9) == NUL
2929+ && (fname[9] != NUL
2930+ || (fname[8] != '0' && fname[8] != '1' && fname[8] != '2')));
2931+}
2932+#endif
2933+
2934 #ifdef FEAT_MBYTE
2935
2936 /*
2937@@ -2734,6 +2775,32 @@
2938 #endif
2939
2940 /*
2941+ * Return TRUE if a file appears to be read-only from the file permissions.
2942+ */
2943+ int
2944+check_file_readonly(fname, perm)
2945+ char_u *fname; /* full path to file */
2946+ int perm; /* known permissions on file */
2947+{
2948+#ifndef USE_MCH_ACCESS
2949+ int fd = 0;
2950+#endif
2951+
2952+ return (
2953+#ifdef USE_MCH_ACCESS
2954+# ifdef UNIX
2955+ (perm & 0222) == 0 ||
2956+# endif
2957+ mch_access((char *)fname, W_OK)
2958+#else
2959+ (fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0
2960+ ? TRUE : (close(fd), FALSE)
2961+#endif
2962+ );
2963+}
2964+
2965+
2966+/*
2967 * buf_write() - write to file "fname" lines "start" through "end"
2968 *
2969 * We do our own buffering here because fwrite() is so slow.
2970@@ -3219,17 +3286,8 @@
2971 * Check if the file is really writable (when renaming the file to
2972 * make a backup we won't discover it later).
2973 */
2974- file_readonly = (
2975-# ifdef USE_MCH_ACCESS
2976-# ifdef UNIX
2977- (perm & 0222) == 0 ||
2978-# endif
2979- mch_access((char *)fname, W_OK)
2980-# else
2981- (fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0
2982- ? TRUE : (close(fd), FALSE)
2983-# endif
2984- );
2985+ file_readonly = check_file_readonly(fname, (int)perm);
2986+
2987 if (!forceit && file_readonly)
2988 {
2989 if (vim_strchr(p_cpo, CPO_FWRITE) != NULL)
[c2aa910]2990@@ -5495,6 +5553,8 @@
2991 }
2992 #endif
2993
2994+#if defined(FEAT_VIMINFO) || defined(FEAT_BROWSE) || \
2995+ defined(FEAT_QUICKFIX) || defined(PROTO)
2996 /*
2997 * Try to find a shortname by comparing the fullname with the current
2998 * directory.
2999@@ -5548,6 +5608,7 @@
3000 p = NULL;
3001 return p;
3002 }
3003+#endif
3004
3005 /*
3006 * Shorten filenames for all buffers.
3007@@ -7107,6 +7168,7 @@
3008
3009 static event_T last_event;
3010 static int last_group;
3011+static int autocmd_blocked = 0; /* block all autocmds */
3012
3013 /*
3014 * Show the autocommands for one AutoPat.
3015@@ -8396,7 +8458,7 @@
3016 * Quickly return if there are no autocommands for this event or
3017 * autocommands are blocked.
3018 */
3019- if (first_autopat[(int)event] == NULL || autocmd_block > 0)
3020+ if (first_autopat[(int)event] == NULL || autocmd_blocked > 0)
3021 goto BYPASS_AU;
3022
3023 /*
3024@@ -8710,6 +8772,40 @@
3025 return retval;
3026 }
3027
3028+# ifdef FEAT_EVAL
3029+static char_u *old_termresponse = NULL;
3030+# endif
3031+
3032+/*
3033+ * Block triggering autocommands until unblock_autocmd() is called.
3034+ * Can be used recursively, so long as it's symmetric.
3035+ */
3036+ void
3037+block_autocmds()
3038+{
3039+# ifdef FEAT_EVAL
3040+ /* Remember the value of v:termresponse. */
3041+ if (autocmd_blocked == 0)
3042+ old_termresponse = get_vim_var_str(VV_TERMRESPONSE);
3043+# endif
3044+ ++autocmd_blocked;
3045+}
3046+
3047+ void
3048+unblock_autocmds()
3049+{
3050+ --autocmd_blocked;
3051+
3052+# ifdef FEAT_EVAL
3053+ /* When v:termresponse was set while autocommands were blocked, trigger
3054+ * the autocommands now. Esp. useful when executing a shell command
3055+ * during startup (vimdiff). */
3056+ if (autocmd_blocked == 0
3057+ && get_vim_var_str(VV_TERMRESPONSE) != old_termresponse)
3058+ apply_autocmds(EVENT_TERMRESPONSE, NULL, NULL, FALSE, curbuf);
3059+# endif
3060+}
3061+
3062 /*
3063 * Find next autocommand pattern that matches.
3064 */
3065diff -Naur vim71.orig/src/fold.c vim71/src/fold.c
3066--- vim71.orig/src/fold.c 2007-05-07 12:46:32.000000000 -0700
3067+++ vim71/src/fold.c 2007-10-16 14:14:41.000000000 -0700
3068@@ -858,7 +858,14 @@
3069 || foldmethodIsDiff(wp)
3070 #endif
3071 || foldmethodIsSyntax(wp))
3072+ {
3073+ int save_got_int = got_int;
3074+
3075+ /* reset got_int here, otherwise it won't work */
3076+ got_int = FALSE;
3077 foldUpdateIEMS(wp, top, bot);
3078+ got_int |= save_got_int;
3079+ }
3080 }
3081
3082 /* foldUpdateAll() {{{2 */
3083diff -Naur vim71.orig/src/getchar.c vim71/src/getchar.c
3084--- vim71.orig/src/getchar.c 2007-05-07 12:18:20.000000000 -0700
3085+++ vim71/src/getchar.c 2007-10-16 14:14:28.000000000 -0700
3086@@ -1596,8 +1596,16 @@
3087 continue;
3088 }
3089 #endif
3090-
3091 #ifdef FEAT_GUI
3092+ /* Handle focus event here, so that the caller doesn't need to
3093+ * know about it. Return K_IGNORE so that we loop once (needed if
3094+ * 'lazyredraw' is set). */
3095+ if (c == K_FOCUSGAINED || c == K_FOCUSLOST)
3096+ {
3097+ ui_focus_change(c == K_FOCUSGAINED);
3098+ c = K_IGNORE;
3099+ }
3100+
3101 /* Translate K_CSI to CSI. The special key is only used to avoid
3102 * it being recognized as the start of a special key. */
3103 if (c == K_CSI)
3104@@ -1741,6 +1749,22 @@
3105 }
3106
3107 /*
3108+ * Like safe_vgetc(), but loop to handle K_IGNORE.
3109+ * Also ignore scrollbar events.
3110+ */
3111+ int
3112+plain_vgetc()
3113+{
3114+ int c;
3115+
3116+ do
3117+ {
3118+ c = safe_vgetc();
3119+ } while (c == K_IGNORE || c == K_VER_SCROLLBAR || c == K_HOR_SCROLLBAR);
3120+ return c;
3121+}
3122+
3123+/*
3124 * Check if a character is available, such that vgetc() will not block.
3125 * If the next character is a special character or multi-byte, the returned
3126 * character is not valid!.
[ba61c16]3127diff -Naur vim71.orig/src/globals.h vim71/src/globals.h
3128--- vim71.orig/src/globals.h 2007-05-07 12:44:26.000000000 -0700
[c2aa910]3129+++ vim71/src/globals.h 2007-10-16 14:14:31.000000000 -0700
3130@@ -301,13 +301,17 @@
3131 #endif
3132
3133 #ifdef FEAT_EVAL
3134-/* Garbage collection can only take place when we are sure there are no Lists
3135+/*
3136+ * Garbage collection can only take place when we are sure there are no Lists
3137 * or Dictionaries being used internally. This is flagged with
3138 * "may_garbage_collect" when we are at the toplevel.
3139 * "want_garbage_collect" is set by the garbagecollect() function, which means
3140- * we do garbage collection before waiting for a char at the toplevel. */
3141+ * we do garbage collection before waiting for a char at the toplevel.
3142+ * "garbage_collect_at_exit" indicates garbagecollect(1) was called.
3143+ */
3144 EXTERN int may_garbage_collect INIT(= FALSE);
3145 EXTERN int want_garbage_collect INIT(= FALSE);
3146+EXTERN int garbage_collect_at_exit INIT(= FALSE);
3147
3148 /* ID of script being sourced or was sourced to define the current function. */
3149 EXTERN scid_T current_SID INIT(= 0);
3150@@ -362,7 +366,6 @@
3151 EXTERN int autocmd_busy INIT(= FALSE); /* Is apply_autocmds() busy? */
3152 EXTERN int autocmd_no_enter INIT(= FALSE); /* *Enter autocmds disabled */
3153 EXTERN int autocmd_no_leave INIT(= FALSE); /* *Leave autocmds disabled */
3154-EXTERN int autocmd_block INIT(= 0); /* block all autocmds */
3155 EXTERN int modified_was_set; /* did ":set modified" */
3156 EXTERN int did_filetype INIT(= FALSE); /* FileType event found */
3157 EXTERN int keep_filetype INIT(= FALSE); /* value for did_filetype when
3158@@ -801,7 +804,7 @@
[ba61c16]3159 EXTERN int (*mb_char2bytes) __ARGS((int c, char_u *buf)) INIT(= latin_char2bytes);
3160 EXTERN int (*mb_ptr2cells) __ARGS((char_u *p)) INIT(= latin_ptr2cells);
3161 EXTERN int (*mb_char2cells) __ARGS((int c)) INIT(= latin_char2cells);
3162-EXTERN int (*mb_off2cells) __ARGS((unsigned off)) INIT(= latin_off2cells);
3163+EXTERN int (*mb_off2cells) __ARGS((unsigned off, unsigned max_off)) INIT(= latin_off2cells);
3164 EXTERN int (*mb_ptr2char) __ARGS((char_u *p)) INIT(= latin_ptr2char);
3165 EXTERN int (*mb_head_off) __ARGS((char_u *base, char_u *p)) INIT(= latin_head_off);
3166
3167diff -Naur vim71.orig/src/gui.c vim71/src/gui.c
3168--- vim71.orig/src/gui.c 2007-05-07 12:50:55.000000000 -0700
[c2aa910]3169+++ vim71/src/gui.c 2007-10-16 14:14:28.000000000 -0700
[ba61c16]3170@@ -1080,7 +1080,8 @@
3171 cur_width = gui.char_width;
3172 }
3173 #ifdef FEAT_MBYTE
3174- if (has_mbyte && (*mb_off2cells)(LineOffset[gui.row] + gui.col) > 1)
3175+ if (has_mbyte && (*mb_off2cells)(LineOffset[gui.row] + gui.col,
3176+ LineOffset[gui.row] + screen_Columns) > 1)
3177 {
3178 /* Double wide character. */
3179 if (shape_table[idx].shape != SHAPE_VER)
3180@@ -1159,7 +1160,7 @@
3181 #endif
3182
3183 # if defined(FEAT_GUI_TABLINE) && (defined(FEAT_GUI_MSWIN) \
3184- || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_MAC))
3185+ || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_MAC))
3186 if (gui_has_tabline())
3187 text_area_y += gui.tabline_height;
3188 #endif
[c2aa910]3189@@ -4518,7 +4519,18 @@
3190 xim_set_focus(in_focus);
3191 # endif
3192
3193- ui_focus_change(in_focus);
3194+ /* Put events in the input queue only when allowed.
3195+ * ui_focus_change() isn't called directly, because it invokes
3196+ * autocommands and that must not happen asynchronously. */
3197+ if (!hold_gui_events)
3198+ {
3199+ char_u bytes[3];
3200+
3201+ bytes[0] = CSI;
3202+ bytes[1] = KS_EXTRA;
3203+ bytes[2] = in_focus ? (int)KE_FOCUSGAINED : (int)KE_FOCUSLOST;
3204+ add_to_input_buf(bytes, 3);
3205+ }
3206 #endif
3207 }
3208
3209@@ -5117,7 +5129,7 @@
[ba61c16]3210 p = vim_strsave_escaped(fnames[i], (char_u *)"\\ \t\"|");
3211 # endif
3212 if (p != NULL)
3213- add_to_input_buf(p, (int)STRLEN(p));
3214+ add_to_input_buf_csi(p, (int)STRLEN(p));
3215 vim_free(p);
3216 vim_free(fnames[i]);
3217 }
3218diff -Naur vim71.orig/src/gui_gtk.c vim71/src/gui_gtk.c
3219--- vim71.orig/src/gui_gtk.c 2007-05-10 01:37:37.000000000 -0700
[c2aa910]3220+++ vim71/src/gui_gtk.c 2007-10-16 14:14:12.000000000 -0700
[ba61c16]3221@@ -53,8 +53,8 @@
3222 # ifdef bindtextdomain
3223 # undef bindtextdomain
3224 # endif
3225-# ifdef bindtextdomain_codeset
3226-# undef bindtextdomain_codeset
3227+# ifdef bind_textdomain_codeset
3228+# undef bind_textdomain_codeset
3229 # endif
3230 # if defined(FEAT_GETTEXT) && !defined(ENABLE_NLS)
3231 # define ENABLE_NLS /* so the texts in the dialog boxes are translated */
3232@@ -1630,11 +1630,14 @@
3233 */
3234 /*ARGSUSED*/
3235 static int
3236-dlg_key_press_event(GtkWidget * widget, GdkEventKey * event, CancelData *data)
3237+dlg_key_press_event(GtkWidget *widget, GdkEventKey *event, CancelData *data)
3238 {
3239- /* Ignore hitting Enter when there is no default button. */
3240- if (data->ignore_enter && event->keyval == GDK_Return)
3241+ /* Ignore hitting Enter (or Space) when there is no default button. */
3242+ if (data->ignore_enter && (event->keyval == GDK_Return
3243+ || event->keyval == ' '))
3244 return TRUE;
3245+ else /* A different key was pressed, return to normal behavior */
3246+ data->ignore_enter = FALSE;
3247
3248 if (event->keyval != GDK_Escape && event->keyval != GDK_Return)
3249 return FALSE;
3250@@ -2224,6 +2227,13 @@
3251 {
3252 DialogInfo *di = (DialogInfo *)data;
3253
3254+ /* Ignore hitting Enter (or Space) when there is no default button. */
3255+ if (di->ignore_enter && (event->keyval == GDK_Return
3256+ || event->keyval == ' '))
3257+ return TRUE;
3258+ else /* A different key was pressed, return to normal behavior */
3259+ di->ignore_enter = FALSE;
3260+
3261 /* Close the dialog when hitting "Esc". */
3262 if (event->keyval == GDK_Escape)
3263 {
3264diff -Naur vim71.orig/src/gui_gtk_x11.c vim71/src/gui_gtk_x11.c
3265--- vim71.orig/src/gui_gtk_x11.c 2007-05-10 01:37:49.000000000 -0700
[c2aa910]3266+++ vim71/src/gui_gtk_x11.c 2007-10-16 14:14:28.000000000 -0700
[ba61c16]3267@@ -36,8 +36,8 @@
3268 # ifdef bindtextdomain
3269 # undef bindtextdomain
3270 # endif
3271-# ifdef bindtextdomain_codeset
3272-# undef bindtextdomain_codeset
3273+# ifdef bind_textdomain_codeset
3274+# undef bind_textdomain_codeset
3275 # endif
3276 # if defined(FEAT_GETTEXT) && !defined(ENABLE_NLS)
3277 # define ENABLE_NLS /* so the texts in the dialog boxes are translated */
[c2aa910]3278@@ -813,10 +813,15 @@
3279 if (blink_state == BLINK_NONE)
3280 gui_mch_start_blink();
3281
3282- /* make sure keyboard input goes to the draw area (if this is focus for a window) */
3283+ /* make sure keyboard input goes to the draw area (if this is focus for a
3284+ * window) */
3285 if (widget != gui.drawarea)
3286 gtk_widget_grab_focus(gui.drawarea);
3287
3288+ /* make sure the input buffer is read */
3289+ if (gtk_main_level() > 0)
3290+ gtk_main_quit();
3291+
3292 return TRUE;
3293 }
3294
3295@@ -829,6 +834,10 @@
3296 if (blink_state != BLINK_NONE)
3297 gui_mch_stop_blink();
3298
3299+ /* make sure the input buffer is read */
3300+ if (gtk_main_level() > 0)
3301+ gtk_main_quit();
3302+
3303 return TRUE;
3304 }
3305
3306@@ -2188,8 +2197,10 @@
[ba61c16]3307 escaped_filename = vim_strsave_escaped(filename, escape_chars);
3308 if (escaped_filename == NULL)
3309 return FALSE;
3310- mksession_cmdline = g_strconcat("mksession ", (char *)escaped_filename, NULL);
3311+ mksession_cmdline = g_strconcat("mksession ", (char *)escaped_filename,
3312+ NULL);
3313 vim_free(escaped_filename);
3314+
3315 /*
3316 * Use a reasonable hardcoded set of 'sessionoptions' flags to avoid
3317 * unpredictable effects when the session is saved automatically. Also,
[c2aa910]3318@@ -2199,7 +2210,7 @@
[ba61c16]3319 */
3320 save_ssop_flags = ssop_flags;
3321 ssop_flags = (SSOP_BLANK|SSOP_CURDIR|SSOP_FOLDS|SSOP_GLOBALS
3322- |SSOP_HELP|SSOP_OPTIONS|SSOP_WINSIZE);
3323+ |SSOP_HELP|SSOP_OPTIONS|SSOP_WINSIZE|SSOP_TABPAGES);
3324
3325 do_cmdline_cmd((char_u *)"let Save_VV_this_session = v:this_session");
3326 failed = (do_cmdline_cmd((char_u *)mksession_cmdline) == FAIL);
[c2aa910]3327@@ -3212,8 +3223,9 @@
3328 {
3329 if (clicked_page == 0)
3330 {
3331- /* Click after all tabs moves to next tab page. */
3332- if (send_tabline_event(0) && gtk_main_level() > 0)
3333+ /* Click after all tabs moves to next tab page. When "x" is
3334+ * small guess it's the left button. */
3335+ if (send_tabline_event(x < 50 ? -1 : 0) && gtk_main_level() > 0)
3336 gtk_main_quit();
3337 }
3338 #ifndef HAVE_GTK2
[ba61c16]3339diff -Naur vim71.orig/src/if_cscope.c vim71/src/if_cscope.c
3340--- vim71.orig/src/if_cscope.c 2007-03-11 07:29:57.000000000 -0700
[c2aa910]3341+++ vim71/src/if_cscope.c 2007-10-16 14:14:28.000000000 -0700
3342@@ -24,11 +24,6 @@
3343 /* not UNIX, must be WIN32 */
3344 # include "vimio.h"
3345 # include <fcntl.h>
3346-# include <process.h>
3347-# define STDIN_FILENO 0
3348-# define STDOUT_FILENO 1
3349-# define STDERR_FILENO 2
3350-# define pipe(fds) _pipe(fds, 256, O_TEXT|O_NOINHERIT)
3351 #endif
3352 #include "if_cscope.h"
3353
3354@@ -65,7 +60,7 @@
3355 static char * cs_parse_results __ARGS((int cnumber, char *buf, int bufsize, char **context, char **linenumber, char **search));
3356 static char * cs_pathcomponents __ARGS((char *path));
3357 static void cs_print_tags_priv __ARGS((char **, char **, int));
3358-static int cs_read_prompt __ARGS((int ));
3359+static int cs_read_prompt __ARGS((int));
3360 static void cs_release_csp __ARGS((int, int freefnpp));
3361 static int cs_reset __ARGS((exarg_T *eap));
3362 static char * cs_resolve_file __ARGS((int, char *));
3363@@ -73,6 +68,8 @@
[ba61c16]3364
3365
3366 static csinfo_T csinfo[CSCOPE_MAX_CONNECTIONS];
3367+static int eap_arg_len; /* length of eap->arg, set in
3368+ cs_lookup_cmd() */
3369 static cscmd_T cs_cmds[] =
3370 {
3371 { "add", cs_add,
[c2aa910]3372@@ -260,14 +257,7 @@
[ba61c16]3373
3374 if ((p = cs_manage_matches(NULL, NULL, -1, Get)) == NULL)
3375 return TRUE;
3376-
3377- if ((int)strlen(p) > size)
3378- {
3379- strncpy((char *)buf, p, size - 1);
3380- buf[size] = '\0';
3381- }
3382- else
3383- (void)strcpy((char *)buf, p);
3384+ vim_strncpy(buf, (char_u *)p, size - 1);
3385
3386 return FALSE;
3387 } /* cs_fgets */
[c2aa910]3388@@ -386,7 +376,7 @@
[ba61c16]3389 * PRIVATE: cs_add
3390 *
3391 * add cscope database or a directory name (to look for cscope.out)
3392- * the the cscope connection list
3393+ * to the cscope connection list
3394 *
3395 * MAXPATHL 256
3396 */
[c2aa910]3397@@ -509,7 +499,7 @@
3398 #if defined(UNIX)
3399 else if (S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode))
3400 #else
3401- /* substitute define S_ISREG from os_unix.h */
3402+ /* WIN32 - substitute define S_ISREG from os_unix.h */
3403 else if (((statbuf.st_mode) & S_IFMT) == S_IFREG)
3404 #endif
3405 {
3406@@ -722,17 +712,32 @@
3407 cs_create_connection(i)
3408 int i;
3409 {
3410- int to_cs[2], from_cs[2], len;
3411- char *prog, *cmd, *ppath = NULL;
3412-#ifndef UNIX
3413- int in_save, out_save, err_save;
3414- long_i ph;
3415-# ifdef FEAT_GUI
3416- HWND activewnd = NULL;
3417- HWND consolewnd = NULL;
3418+#ifdef UNIX
3419+ int to_cs[2], from_cs[2];
3420+#endif
3421+ int len;
3422+ char *prog, *cmd, *ppath = NULL;
3423+#ifdef WIN32
3424+ int fd;
3425+ SECURITY_ATTRIBUTES sa;
3426+ PROCESS_INFORMATION pi;
3427+ STARTUPINFO si;
3428+ BOOL pipe_stdin = FALSE, pipe_stdout = FALSE;
3429+ HANDLE stdin_rd, stdout_rd;
3430+ HANDLE stdout_wr, stdin_wr;
3431+ BOOL created;
3432+# ifdef __BORLANDC__
3433+# define OPEN_OH_ARGTYPE long
3434+# else
3435+# if (_MSC_VER >= 1300)
3436+# define OPEN_OH_ARGTYPE intptr_t
3437+# else
3438+# define OPEN_OH_ARGTYPE long
3439+# endif
3440 # endif
3441 #endif
3442
3443+#if defined(UNIX)
3444 /*
3445 * Cscope reads from to_cs[0] and writes to from_cs[1]; vi reads from
3446 * from_cs[0] and writes to to_cs[1].
3447@@ -753,18 +758,12 @@
3448 return CSCOPE_FAILURE;
3449 }
3450
3451-#if defined(UNIX)
3452 switch (csinfo[i].pid = fork())
3453 {
3454 case -1:
3455 (void)EMSG(_("E622: Could not fork for cscope"));
3456 goto err_closing;
3457 case 0: /* child: run cscope. */
3458-#else
3459- in_save = dup(STDIN_FILENO);
3460- out_save = dup(STDOUT_FILENO);
3461- err_save = dup(STDERR_FILENO);
3462-#endif
3463 if (dup2(to_cs[0], STDIN_FILENO) == -1)
3464 PERROR("cs_create_connection 1");
3465 if (dup2(from_cs[1], STDOUT_FILENO) == -1)
3466@@ -773,15 +772,32 @@
3467 PERROR("cs_create_connection 3");
3468
3469 /* close unused */
3470-#if defined(UNIX)
3471 (void)close(to_cs[1]);
3472 (void)close(from_cs[0]);
3473 #else
3474- /* On win32 we must close opposite ends because we are the parent */
3475- (void)close(to_cs[0]);
3476- to_cs[0] = -1;
3477- (void)close(from_cs[1]);
3478- from_cs[1] = -1;
3479+ /* WIN32 */
3480+ /* Create pipes to communicate with cscope */
3481+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
3482+ sa.bInheritHandle = TRUE;
3483+ sa.lpSecurityDescriptor = NULL;
3484+
3485+ if (!(pipe_stdin = CreatePipe(&stdin_rd, &stdin_wr, &sa, 0))
3486+ || !(pipe_stdout = CreatePipe(&stdout_rd, &stdout_wr, &sa, 0)))
3487+ {
3488+ (void)EMSG(_("E566: Could not create cscope pipes"));
3489+err_closing:
3490+ if (pipe_stdin)
3491+ {
3492+ CloseHandle(stdin_rd);
3493+ CloseHandle(stdin_wr);
3494+ }
3495+ if (pipe_stdout)
3496+ {
3497+ CloseHandle(stdout_rd);
3498+ CloseHandle(stdout_wr);
3499+ }
3500+ return CSCOPE_FAILURE;
3501+ }
3502 #endif
3503 /* expand the cscope exec for env var's */
3504 if ((prog = (char *)alloc(MAXPATHL + 1)) == NULL)
3505@@ -789,6 +805,7 @@
3506 #ifdef UNIX
3507 return CSCOPE_FAILURE;
3508 #else
3509+ /* WIN32 */
3510 goto err_closing;
3511 #endif
3512 }
3513@@ -805,6 +822,7 @@
3514 #ifdef UNIX
3515 return CSCOPE_FAILURE;
3516 #else
3517+ /* WIN32 */
3518 goto err_closing;
3519 #endif
3520 }
3521@@ -823,6 +841,7 @@
3522 #ifdef UNIX
3523 return CSCOPE_FAILURE;
3524 #else
3525+ /* WIN32 */
3526 goto err_closing;
3527 #endif
3528 }
3529@@ -831,6 +850,7 @@
3530 #if defined(UNIX)
3531 (void)sprintf(cmd, "exec %s -dl -f %s", prog, csinfo[i].fname);
3532 #else
3533+ /* WIN32 */
3534 (void)sprintf(cmd, "%s -dl -f %s", prog, csinfo[i].fname);
3535 #endif
3536 if (csinfo[i].ppath != NULL)
3537@@ -856,60 +876,6 @@
3538 exit(127);
3539 /* NOTREACHED */
3540 default: /* parent. */
3541-#else
3542-# ifdef FEAT_GUI
3543- activewnd = GetForegroundWindow(); /* on win9x cscope steals focus */
3544- /* Dirty hack to hide annoying console window */
3545- if (AllocConsole())
3546- {
3547- char *title;
3548- title = (char *)alloc(1024);
3549- if (title == NULL)
3550- FreeConsole();
3551- else
3552- {
3553- GetConsoleTitle(title, 1024); /* save for future restore */
3554- SetConsoleTitle(
3555- "GVIMCS{5499421B-CBEF-45b0-85EF-38167FDEA5C5}GVIMCS");
3556- Sleep(40); /* as stated in MS KB we must wait 40 ms */
3557- consolewnd = FindWindow(NULL,
3558- "GVIMCS{5499421B-CBEF-45b0-85EF-38167FDEA5C5}GVIMCS");
3559- if (consolewnd != NULL)
3560- ShowWindow(consolewnd, SW_HIDE);
3561- SetConsoleTitle(title);
3562- vim_free(title);
3563- }
3564- }
3565-# endif
3566- /* May be use &shell, &shellquote etc */
3567-# ifdef __BORLANDC__
3568- /* BCC 5.5 uses a different function name for spawnlp */
3569- ph = (long_i)spawnlp(P_NOWAIT, prog, cmd, NULL);
3570-# else
3571- ph = (long_i)_spawnlp(_P_NOWAIT, prog, cmd, NULL);
3572-# endif
3573- vim_free(prog);
3574- vim_free(cmd);
3575-# ifdef FEAT_GUI
3576- /* Dirty hack part two */
3577- if (activewnd != NULL)
3578- /* restoring focus */
3579- SetForegroundWindow(activewnd);
3580- if (consolewnd != NULL)
3581- FreeConsole();
3582-
3583-# endif
3584- if (ph == -1)
3585- {
3586- PERROR(_("cs_create_connection exec failed"));
3587- (void)EMSG(_("E623: Could not spawn cscope process"));
3588- goto err_closing;
3589- }
3590- /* else */
3591- csinfo[i].pid = 0;
3592- csinfo[i].hProc = (HANDLE)ph;
3593-
3594-#endif /* !UNIX */
3595 /*
3596 * Save the file descriptors for later duplication, and
3597 * reopen as streams.
3598@@ -919,22 +885,54 @@
3599 if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL)
3600 PERROR(_("cs_create_connection: fdopen for fr_fp failed"));
3601
3602-#if defined(UNIX)
3603 /* close unused */
3604 (void)close(to_cs[0]);
3605 (void)close(from_cs[1]);
3606
3607 break;
3608 }
3609+
3610 #else
3611- /* restore stdhandles */
3612- dup2(in_save, STDIN_FILENO);
3613- dup2(out_save, STDOUT_FILENO);
3614- dup2(err_save, STDERR_FILENO);
3615- close(in_save);
3616- close(out_save);
3617- close(err_save);
3618-#endif
3619+ /* WIN32 */
3620+ /* Create a new process to run cscope and use pipes to talk with it */
3621+ GetStartupInfo(&si);
3622+ si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3623+ si.wShowWindow = SW_HIDE; /* Hide child application window */
3624+ si.hStdOutput = stdout_wr;
3625+ si.hStdError = stdout_wr;
3626+ si.hStdInput = stdin_rd;
3627+ created = CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE,
3628+ NULL, NULL, &si, &pi);
3629+ vim_free(prog);
3630+ vim_free(cmd);
3631+
3632+ if (!created)
3633+ {
3634+ PERROR(_("cs_create_connection exec failed"));
3635+ (void)EMSG(_("E623: Could not spawn cscope process"));
3636+ goto err_closing;
3637+ }
3638+ /* else */
3639+ csinfo[i].pid = pi.dwProcessId;
3640+ csinfo[i].hProc = pi.hProcess;
3641+ CloseHandle(pi.hThread);
3642+
3643+ /* TODO - tidy up after failure to create files on pipe handles. */
3644+ if (((fd = _open_osfhandle((OPEN_OH_ARGTYPE)stdin_wr,
3645+ _O_TEXT|_O_APPEND)) < 0)
3646+ || ((csinfo[i].to_fp = _fdopen(fd, "w")) == NULL))
3647+ PERROR(_("cs_create_connection: fdopen for to_fp failed"));
3648+ if (((fd = _open_osfhandle((OPEN_OH_ARGTYPE)stdout_rd,
3649+ _O_TEXT|_O_RDONLY)) < 0)
3650+ || ((csinfo[i].fr_fp = _fdopen(fd, "r")) == NULL))
3651+ PERROR(_("cs_create_connection: fdopen for fr_fp failed"));
3652+
3653+ /* Close handles for file descriptors inherited by the cscope process */
3654+ CloseHandle(stdin_rd);
3655+ CloseHandle(stdout_wr);
3656+
3657+#endif /* !UNIX */
3658+
3659 return CSCOPE_SUCCESS;
3660 } /* cs_create_connection */
3661
3662@@ -966,7 +964,7 @@
[ba61c16]3663 }
3664
3665 pat = opt + strlen(opt) + 1;
3666- if (pat == NULL || (pat != NULL && pat[0] == '\0'))
3667+ if (pat >= (char *)eap->arg + eap_arg_len)
3668 {
3669 cs_usage_msg(Find);
3670 return FALSE;
[c2aa910]3671@@ -1317,7 +1315,7 @@
[ba61c16]3672 #else
3673 /* compare pathnames first */
3674 && ((fullpathcmp(csinfo[j].fname, fname, FALSE) & FPC_SAME)
3675- /* if not Windows 9x, test index file atributes too */
3676+ /* if not Windows 9x, test index file attributes too */
3677 || (!mch_windows95()
3678 && csinfo[j].nVolume == bhfi.dwVolumeSerialNumber
3679 && csinfo[j].nIndexHigh == bhfi.nFileIndexHigh
[c2aa910]3680@@ -1401,6 +1399,9 @@
[ba61c16]3681 if (eap->arg == NULL)
3682 return NULL;
3683
3684+ /* Store length of eap->arg before it gets modified by strtok(). */
3685+ eap_arg_len = STRLEN(eap->arg);
3686+
3687 if ((stok = strtok((char *)(eap->arg), (const char *)" ")) == NULL)
3688 return NULL;
3689
[c2aa910]3690@@ -2099,8 +2100,8 @@
3691 /*
3692 * PRIVATE: cs_release_csp
3693 *
3694- * does the actual free'ing for the cs ptr with an optional flag of whether
3695- * or not to free the filename. called by cs_kill and cs_reset.
3696+ * Does the actual free'ing for the cs ptr with an optional flag of whether
3697+ * or not to free the filename. Called by cs_kill and cs_reset.
3698 */
3699 static void
3700 cs_release_csp(i, freefnpp)
3701@@ -2118,10 +2119,13 @@
3702 (void)fputs("q\n", csinfo[i].to_fp);
3703 (void)fflush(csinfo[i].to_fp);
3704 }
3705- /* give cscope chance to exit normally */
3706- if (csinfo[i].hProc != NULL
3707- && WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT)
3708- TerminateProcess(csinfo[i].hProc, 0);
3709+ if (csinfo[i].hProc != NULL)
3710+ {
3711+ /* Give cscope a chance to exit normally */
3712+ if (WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT)
3713+ TerminateProcess(csinfo[i].hProc, 0);
3714+ CloseHandle(csinfo[i].hProc);
3715+ }
3716 #endif
3717
3718 if (csinfo[i].fr_fp != NULL)
3719@@ -2195,7 +2199,7 @@
[ba61c16]3720 cs_add_common(dblist[i], pplist[i], fllist[i]);
3721 if (p_csverbose)
3722 {
3723- /* dont' use smsg_attr because want to display
3724+ /* don't use smsg_attr() because we want to display the
3725 * connection number in the same line as
3726 * "Added cscope database..."
3727 */
[c2aa910]3728@@ -2304,6 +2308,21 @@
3729 return CSCOPE_SUCCESS;
3730 } /* cs_show */
3731
3732+
3733+/*
3734+ * PUBLIC: cs_end
3735+ *
3736+ * Only called when VIM exits to quit any cscope sessions.
3737+ */
3738+ void
3739+cs_end()
3740+{
3741+ int i;
3742+
3743+ for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
3744+ cs_release_csp(i, TRUE);
3745+}
3746+
3747 #endif /* FEAT_CSCOPE */
3748
3749 /* the end */
3750diff -Naur vim71.orig/src/if_cscope.h vim71/src/if_cscope.h
3751--- vim71.orig/src/if_cscope.h 2005-06-30 10:14:22.000000000 -0700
3752+++ vim71/src/if_cscope.h 2007-10-16 14:14:28.000000000 -0700
3753@@ -72,7 +72,7 @@
3754 ino_t st_ino; /* inode number of cscope db */
3755 #else
3756 # if defined(WIN32)
3757- int pid; /* Can't get pid so set it to 0 ;) */
3758+ DWORD pid; /* PID of the connected cscope process. */
3759 HANDLE hProc; /* cscope process handle */
3760 DWORD nVolume; /* Volume serial number, instead of st_dev */
3761 DWORD nIndexHigh; /* st_ino has no meaning in the Windows */
[ba61c16]3762diff -Naur vim71.orig/src/if_mzsch.c vim71/src/if_mzsch.c
3763--- vim71.orig/src/if_mzsch.c 2007-05-12 04:13:47.000000000 -0700
[c2aa910]3764+++ vim71/src/if_mzsch.c 2007-10-16 14:14:06.000000000 -0700
[ba61c16]3765@@ -308,6 +308,8 @@
3766 static Scheme_Config *(*dll_scheme_current_config)(void);
3767 static Scheme_Object *(*dll_scheme_char_string_to_byte_string)
3768 (Scheme_Object *s);
3769+static Scheme_Object *(*dll_scheme_char_string_to_path)
3770+ (Scheme_Object *s);
3771 # endif
3772
3773 /* arrays are imported directly */
3774@@ -398,6 +400,8 @@
3775 # define scheme_current_config dll_scheme_current_config
3776 # define scheme_char_string_to_byte_string \
3777 dll_scheme_char_string_to_byte_string
3778+# define scheme_char_string_to_path \
3779+ dll_scheme_char_string_to_path
3780 # endif
3781
3782 typedef struct
3783@@ -498,6 +502,8 @@
3784 {"scheme_current_config", (void **)&dll_scheme_current_config},
3785 {"scheme_char_string_to_byte_string",
3786 (void **)&dll_scheme_char_string_to_byte_string},
3787+ {"scheme_char_string_to_path",
3788+ (void **)&dll_scheme_char_string_to_path},
3789 # endif
3790 {NULL, NULL}};
3791
3792@@ -773,7 +779,14 @@
3793 #ifdef MZSCHEME_COLLECTS
3794 /* setup 'current-library-collection-paths' parameter */
3795 scheme_set_param(scheme_config, MZCONFIG_COLLECTION_PATHS,
3796- scheme_make_pair(scheme_make_string(MZSCHEME_COLLECTS),
3797+ scheme_make_pair(
3798+# if MZSCHEME_VERSION_MAJOR >= 299
3799+ scheme_char_string_to_path(
3800+ scheme_byte_string_to_char_string(
3801+ scheme_make_byte_string(MZSCHEME_COLLECTS))),
3802+# else
3803+ scheme_make_string(MZSCHEME_COLLECTS),
3804+# endif
3805 scheme_null));
3806 #endif
3807 #ifdef HAVE_SANDBOX
[c2aa910]3808diff -Naur vim71.orig/src/if_perl.xs vim71/src/if_perl.xs
3809--- vim71.orig/src/if_perl.xs 2006-08-16 05:45:15.000000000 -0700
3810+++ vim71/src/if_perl.xs 2007-10-16 14:14:41.000000000 -0700
3811@@ -40,6 +40,28 @@
3812 # define PERL_SUBVERSION SUBVERSION
3813 #endif
3814
3815+/*
3816+ * Quoting Jan Dubois of Active State:
3817+ * ActivePerl build 822 still identifies itself as 5.8.8 but already
3818+ * contains many of the changes from the upcoming Perl 5.8.9 release.
3819+ *
3820+ * The changes include addition of two symbols (Perl_sv_2iv_flags,
3821+ * Perl_newXS_flags) not present in earlier releases.
3822+ *
3823+ * Jan Dubois suggested the following guarding scheme.
3824+ *
3825+ * Active State defined ACTIVEPERL_VERSION as a string in versions before
3826+ * 5.8.8; and so the comparison to 822 below needs to be guarded.
3827+ */
3828+#if (PERL_REVISION == 5) && (PERL_VERSION == 8) && (PERL_SUBVERSION >= 8)
3829+# if (ACTIVEPERL_VERSION >= 822) || (PERL_SUBVERSION >= 9)
3830+# define PERL589_OR_LATER
3831+# endif
3832+#endif
3833+#if (PERL_REVISION == 5) && (PERL_VERSION >= 9)
3834+# define PERL589_OR_LATER
3835+#endif
3836+
3837 #ifndef pTHX
3838 # define pTHX void
3839 # define pTHX_
3840@@ -109,6 +131,10 @@
3841 # else
3842 # define Perl_sv_catpvn dll_Perl_sv_catpvn
3843 # endif
3844+#ifdef PERL589_OR_LATER
3845+# define Perl_sv_2iv_flags dll_Perl_sv_2iv_flags
3846+# define Perl_newXS_flags dll_Perl_newXS_flags
3847+#endif
3848 # define Perl_sv_free dll_Perl_sv_free
3849 # define Perl_sv_isa dll_Perl_sv_isa
3850 # define Perl_sv_magic dll_Perl_sv_magic
3851@@ -192,6 +218,10 @@
3852 #else
3853 static void (*Perl_sv_catpvn)(pTHX_ SV*, const char*, STRLEN);
3854 #endif
3855+#ifdef PERL589_OR_LATER
3856+static IV (*Perl_sv_2iv_flags)(pTHX_ SV* sv, I32 flags);
3857+static CV * (*Perl_newXS_flags)(pTHX_ const char *name, XSUBADDR_t subaddr, const char *const filename, const char *const proto, U32 flags);
3858+#endif
3859 static void (*Perl_sv_free)(pTHX_ SV*);
3860 static int (*Perl_sv_isa)(pTHX_ SV*, const char*);
3861 static void (*Perl_sv_magic)(pTHX_ SV*, SV*, int, const char*, I32);
3862@@ -267,6 +297,10 @@
3863 #else
3864 {"Perl_sv_2pv", (PERL_PROC*)&Perl_sv_2pv},
3865 #endif
3866+#ifdef PERL589_OR_LATER
3867+ {"Perl_sv_2iv_flags", (PERL_PROC*)&Perl_sv_2iv_flags},
3868+ {"Perl_newXS_flags", (PERL_PROC*)&Perl_newXS_flags},
3869+#endif
3870 {"Perl_sv_bless", (PERL_PROC*)&Perl_sv_bless},
3871 #if (PERL_REVISION == 5) && (PERL_VERSION >= 8)
3872 {"Perl_sv_catpvn_flags", (PERL_PROC*)&Perl_sv_catpvn_flags},
3873@@ -411,13 +445,13 @@
3874 char *next;
3875 char *token = (char *)s;
3876
3877- while ((next = strchr(token, '\n')))
3878+ while ((next = strchr(token, '\n')) && !got_int)
3879 {
3880 *next++ = '\0'; /* replace \n with \0 */
3881 msg_attr((char_u *)token, attr);
3882 token = next;
3883 }
3884- if (*token)
3885+ if (*token && !got_int)
3886 msg_attr((char_u *)token, attr);
3887 }
3888
3889diff -Naur vim71.orig/src/if_ruby.c vim71/src/if_ruby.c
3890--- vim71.orig/src/if_ruby.c 2007-05-12 02:54:12.000000000 -0700
3891+++ vim71/src/if_ruby.c 2007-10-16 14:14:28.000000000 -0700
3892@@ -789,7 +789,7 @@
3893 return get_buffer_line(curbuf, curwin->w_cursor.lnum);
3894 }
3895
3896-static VALUE set_current_line(VALUE str)
3897+static VALUE set_current_line(VALUE self, VALUE str)
3898 {
3899 return set_buffer_line(curbuf, curwin->w_cursor.lnum, str);
3900 }
3901diff -Naur vim71.orig/src/keymap.h vim71/src/keymap.h
3902--- vim71.orig/src/keymap.h 2006-08-22 04:38:38.000000000 -0700
3903+++ vim71/src/keymap.h 2007-10-16 14:14:28.000000000 -0700
3904@@ -254,6 +254,8 @@
3905 , KE_DROP /* DnD data is available */
3906 , KE_CURSORHOLD /* CursorHold event */
3907 , KE_NOP /* doesn't do something */
3908+ , KE_FOCUSGAINED /* focus gained */
3909+ , KE_FOCUSLOST /* focus lost */
3910 };
3911
3912 /*
3913@@ -445,6 +447,8 @@
3914 #define K_CMDWIN TERMCAP2KEY(KS_EXTRA, KE_CMDWIN)
3915
3916 #define K_DROP TERMCAP2KEY(KS_EXTRA, KE_DROP)
3917+#define K_FOCUSGAINED TERMCAP2KEY(KS_EXTRA, KE_FOCUSGAINED)
3918+#define K_FOCUSLOST TERMCAP2KEY(KS_EXTRA, KE_FOCUSLOST)
3919
3920 #define K_CURSORHOLD TERMCAP2KEY(KS_EXTRA, KE_CURSORHOLD)
3921
[ba61c16]3922diff -Naur vim71.orig/src/macros.h vim71/src/macros.h
3923--- vim71.orig/src/macros.h 2007-05-07 12:38:22.000000000 -0700
[c2aa910]3924+++ vim71/src/macros.h 2007-10-16 14:14:17.000000000 -0700
[ba61c16]3925@@ -54,10 +54,12 @@
3926
3927 /*
3928 * toupper() and tolower() that use the current locale.
3929- * On some systems toupper()/tolower() only work on lower/uppercase characters
3930+ * On some systems toupper()/tolower() only work on lower/uppercase
3931+ * characters, first use islower() or isupper() then.
3932 * Careful: Only call TOUPPER_LOC() and TOLOWER_LOC() with a character in the
3933 * range 0 - 255. toupper()/tolower() on some systems can't handle others.
3934- * Note: for UTF-8 use utf_toupper() and utf_tolower().
3935+ * Note: It is often better to use MB_TOLOWER() and MB_TOUPPER(), because many
3936+ * toupper() and tolower() implementations only work for ASCII.
3937 */
3938 #ifdef MSWIN
3939 # define TOUPPER_LOC(c) toupper_tab[(c) & 255]
[c2aa910]3940diff -Naur vim71.orig/src/main.aap vim71/src/main.aap
3941--- vim71.orig/src/main.aap 2007-05-07 12:46:43.000000000 -0700
3942+++ vim71/src/main.aap 2007-10-16 14:14:28.000000000 -0700
3943@@ -56,9 +56,16 @@
3944 config {virtual} auto/config.h auto/config.aap :
3945 auto/configure.aap configure.aap
3946 config.arg config.h.in config.aap.in
3947+ # Use "uname -a" to detect the architecture of the system.
3948+ @ok, uname = redir_system('uname -a', 0)
3949+ @if string.find(uname, "i386") >= 0:
3950+ @ arch = "i386"
3951+ @else:
3952+ @ arch = "ppc"
3953+ :print Building for $arch system
3954 :sys CONFIG_STATUS=auto/config.status
3955 ./configure.aap `file2string("config.arg")`
3956- --with-mac-arch=ppc
3957+ --with-mac-arch=$arch
3958 --cache-file=auto/config.cache
3959
3960 # Configure arguments: create an empty "config.arg" file when its missing
3961@@ -1167,7 +1174,7 @@
3962 :symlink `os.getcwd()`/../runtime $RESDIR/vim/runtime
3963 # TODO: Create the vimtutor application.
3964
3965-gui_bundle {virtual}: $(RESDIR) bundle-dir bundle-executable bundle-info
3966+gui_bundle {virtual}: $(RESDIR) bundle-dir bundle-executable bundle-info \
3967 bundle-resource bundle-language
3968
3969 bundle-dir {virtual}: $(APPDIR)/Contents $(VIMTARGET)
3970@@ -1187,7 +1194,7 @@
3971 :sys m4 $(M4FLAGSX) infplist.xml > $(APPDIR)/Contents/Info.plist
3972
3973 bundle-resource {virtual}: bundle-dir bundle-rsrc
3974- :copy {force} $(RSRC_DIR)/*.icns $(RESDIR)
3975+ :copy {force} $(RSRC_DIR)/*.icns $(RESDIR)
3976
3977 ### Classic resources
3978 # Resource fork (in the form of a .rsrc file) for Classic Vim (Mac OS 9)
[ba61c16]3979diff -Naur vim71.orig/src/main.c vim71/src/main.c
3980--- vim71.orig/src/main.c 2007-05-07 12:38:44.000000000 -0700
[c2aa910]3981+++ vim71/src/main.c 2007-10-16 14:14:28.000000000 -0700
[ba61c16]3982@@ -954,7 +954,8 @@
3983 int cmdwin; /* TRUE when working in the command-line window */
3984 int noexmode; /* TRUE when return on entering Ex mode */
3985 {
3986- oparg_T oa; /* operator arguments */
3987+ oparg_T oa; /* operator arguments */
3988+ int previous_got_int = FALSE; /* "got_int" was TRUE */
3989
3990 #if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
3991 /* Setup to catch a terminating error from the X server. Just ignore
3992@@ -1015,12 +1016,32 @@
3993 need_fileinfo = FALSE;
3994 }
3995 }
3996- if (got_int && !global_busy)
3997+
3998+ /* Reset "got_int" now that we got back to the main loop. Except when
3999+ * inside a ":g/pat/cmd" command, then the "got_int" needs to abort
4000+ * the ":g" command.
4001+ * For ":g/pat/vi" we reset "got_int" when used once. When used
4002+ * a second time we go back to Ex mode and abort the ":g" command. */
4003+ if (got_int)
4004 {
4005- if (!quit_more)
4006- (void)vgetc(); /* flush all buffers */
4007- got_int = FALSE;
4008+ if (noexmode && global_busy && !exmode_active && previous_got_int)
4009+ {
4010+ /* Typed two CTRL-C in a row: go back to ex mode as if "Q" was
4011+ * used and keep "got_int" set, so that it aborts ":g". */
4012+ exmode_active = EXMODE_NORMAL;
4013+ State = NORMAL;
4014+ }
4015+ else if (!global_busy || !exmode_active)
4016+ {
4017+ if (!quit_more)
4018+ (void)vgetc(); /* flush all buffers */
4019+ got_int = FALSE;
4020+ }
4021+ previous_got_int = TRUE;
4022 }
4023+ else
4024+ previous_got_int = FALSE;
4025+
4026 if (!exmode_active)
4027 msg_scroll = FALSE;
4028 quit_more = FALSE;
[c2aa910]4029@@ -1309,6 +1330,13 @@
4030 #ifdef FEAT_NETBEANS_INTG
4031 netbeans_end();
4032 #endif
4033+#ifdef FEAT_CSCOPE
4034+ cs_end();
4035+#endif
4036+#ifdef FEAT_EVAL
4037+ if (garbage_collect_at_exit)
4038+ garbage_collect();
4039+#endif
4040
4041 mch_exit(exitval);
4042 }
4043@@ -1360,8 +1388,7 @@
[ba61c16]4044 p = vim_getenv((char_u *)"VIMRUNTIME", &mustfree);
4045 if (p != NULL && *p != NUL)
4046 {
4047- STRCPY(NameBuff, p);
4048- STRCAT(NameBuff, "/lang");
4049+ vim_snprintf((char *)NameBuff, MAXPATHL, "%s/lang", p);
4050 bindtextdomain(VIMPACKAGE, (char *)NameBuff);
4051 }
4052 if (mustfree)
[c2aa910]4053@@ -3632,7 +3659,13 @@
4054 mainerr_arg_missing((char_u *)filev[-1]);
4055 if (mch_dirname(cwd, MAXPATHL) != OK)
4056 return NULL;
4057- if ((p = vim_strsave_escaped_ext(cwd, PATH_ESC_CHARS, '\\', TRUE)) == NULL)
4058+ if ((p = vim_strsave_escaped_ext(cwd,
4059+#ifdef BACKSLASH_IN_FILENAME
4060+ "", /* rem_backslash() will tell what chars to escape */
4061+#else
4062+ PATH_ESC_CHARS,
4063+#endif
4064+ '\\', TRUE)) == NULL)
4065 return NULL;
4066 ga_init2(&ga, 1, 100);
4067 ga_concat(&ga, (char_u *)"<C-\\><C-N>:cd ");
[ba61c16]4068diff -Naur vim71.orig/src/mbyte.c vim71/src/mbyte.c
4069--- vim71.orig/src/mbyte.c 2007-05-07 12:47:09.000000000 -0700
[c2aa910]4070+++ vim71/src/mbyte.c 2007-10-16 14:14:28.000000000 -0700
[ba61c16]4071@@ -1310,20 +1310,26 @@
4072 /*
4073 * mb_off2cells() function pointer.
4074 * Return number of display cells for char at ScreenLines[off].
4075- * Caller must make sure "off" and "off + 1" are valid!
4076+ * We make sure that the offset used is less than "max_off".
4077 */
4078 /*ARGSUSED*/
4079 int
4080-latin_off2cells(off)
4081+latin_off2cells(off, max_off)
4082 unsigned off;
4083+ unsigned max_off;
4084 {
4085 return 1;
4086 }
4087
4088 int
4089-dbcs_off2cells(off)
4090+dbcs_off2cells(off, max_off)
4091 unsigned off;
4092+ unsigned max_off;
4093 {
4094+ /* never check beyond end of the line */
4095+ if (off >= max_off)
4096+ return 1;
4097+
4098 /* Number of cells is equal to number of bytes, except for euc-jp when
4099 * the first byte is 0x8e. */
4100 if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e)
4101@@ -1332,10 +1338,11 @@
4102 }
4103
4104 int
4105-utf_off2cells(off)
4106+utf_off2cells(off, max_off)
4107 unsigned off;
4108+ unsigned max_off;
4109 {
4110- return ScreenLines[off + 1] == 0 ? 2 : 1;
4111+ return (off + 1 < max_off && ScreenLines[off + 1] == 0) ? 2 : 1;
4112 }
4113
4114 /*
4115@@ -2320,7 +2327,7 @@
4116 /* Single byte: first check normally, then with ignore case. */
4117 if (s1[i] != s2[i])
4118 {
4119- cdiff = TOLOWER_LOC(s1[i]) - TOLOWER_LOC(s2[i]);
4120+ cdiff = MB_TOLOWER(s1[i]) - MB_TOLOWER(s2[i]);
4121 if (cdiff != 0)
4122 return cdiff;
4123 }
4124@@ -2899,12 +2906,8 @@
4125 if (composing_hangul)
4126 return TRUE;
4127 #endif
4128- if (enc_dbcs != 0)
4129- return dbcs_off2cells(LineOffset[row] + col) > 1;
4130- if (enc_utf8)
4131- return (col + 1 < Columns
4132- && ScreenLines[LineOffset[row] + col + 1] == 0);
4133- return FALSE;
4134+ return (*mb_off2cells)(LineOffset[row] + col,
4135+ LineOffset[row] + screen_Columns) > 1;
4136 }
4137
4138 # if defined(FEAT_CLIPBOARD) || defined(FEAT_GUI) || defined(FEAT_RIGHTLEFT) \
4139diff -Naur vim71.orig/src/message.c vim71/src/message.c
4140--- vim71.orig/src/message.c 2007-05-07 12:31:59.000000000 -0700
[c2aa910]4141+++ vim71/src/message.c 2007-10-16 14:14:28.000000000 -0700
4142@@ -828,7 +828,7 @@
4143 _("Messages maintainer: Bram Moolenaar <Bram@vim.org>"),
4144 hl_attr(HLF_T));
4145
4146- for (p = first_msg_hist; p != NULL; p = p->next)
4147+ for (p = first_msg_hist; p != NULL && !got_int; p = p->next)
4148 if (p->msg != NULL)
4149 msg_attr(p->msg, p->attr);
4150
4151@@ -944,6 +944,7 @@
4152 c = K_IGNORE;
4153 }
4154 #endif
4155+
4156 /*
4157 * Allow scrolling back in the messages.
4158 * Also accept scroll-down commands when messages fill the screen,
4159@@ -1840,9 +1841,10 @@
4160 char_u *sb_str = str;
4161 int sb_col = msg_col;
[ba61c16]4162 int wrap;
[c2aa910]4163+ int did_last_char;
[ba61c16]4164
4165 did_wait_return = FALSE;
4166- while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
4167+ while ((maxlen < 0 || (int)(s - str) < maxlen) && *s != NUL)
4168 {
4169 /*
4170 * We are at the end of the screen line when:
[c2aa910]4171@@ -1878,7 +1880,7 @@
[ba61c16]4172 /* output postponed text */
4173 t_puts(&t_col, t_s, s, attr);
4174
4175- /* When no more prompt an no more room, truncate here */
4176+ /* When no more prompt and no more room, truncate here */
4177 if (msg_no_more && lines_left == 0)
4178 break;
4179
[c2aa910]4180@@ -1909,7 +1911,10 @@
4181 else
4182 #endif
4183 msg_screen_putchar(*s++, attr);
4184+ did_last_char = TRUE;
4185 }
4186+ else
4187+ did_last_char = FALSE;
4188
4189 if (p_more)
4190 /* store text for scrolling back */
4191@@ -1927,7 +1932,8 @@
[ba61c16]4192 * If screen is completely filled and 'more' is set then wait
4193 * for a character.
4194 */
4195- --lines_left;
4196+ if (lines_left > 0)
4197+ --lines_left;
4198 if (p_more && lines_left == 0 && State != HITRETURN
4199 && !msg_no_more && !exmode_active)
4200 {
[c2aa910]4201@@ -1943,11 +1949,7 @@
4202
4203 /* When we displayed a char in last column need to check if there
4204 * is still more. */
4205- if (*s >= ' '
4206-#ifdef FEAT_RIGHTLEFT
4207- && !cmdmsg_rl
4208-#endif
4209- )
4210+ if (did_last_char)
4211 continue;
4212 }
4213
4214@@ -2234,7 +2236,7 @@
[ba61c16]4215 {
4216 msgchunk_T *mp;
4217
4218- /* Only show somethign if there is more than one line, otherwise it looks
4219+ /* Only show something if there is more than one line, otherwise it looks
4220 * weird, typing a command without output results in one line. */
4221 mp = msg_sb_start(last_msgchunk);
4222 if (mp == NULL || mp->sb_prev == NULL)
[c2aa910]4223@@ -2622,7 +2624,7 @@
[ba61c16]4224 }
4225 }
4226
4227- if (scroll < 0 || (scroll == 0 && mp_last != NULL))
4228+ if (scroll <= 0)
4229 {
4230 /* displayed the requested text, more prompt again */
4231 screen_fill((int)Rows - 1, (int)Rows, 0,
[c2aa910]4232@@ -3456,11 +3458,11 @@
[ba61c16]4233 /* advance to next hotkey and set default hotkey */
4234 #ifdef FEAT_MBYTE
4235 if (has_mbyte)
4236- hotkp += (*mb_ptr2len)(hotkp);
4237+ hotkp += STRLEN(hotkp);
4238 else
4239 #endif
4240 ++hotkp;
4241- (void)copy_char(r + 1, hotkp, TRUE);
4242+ hotkp[copy_char(r + 1, hotkp, TRUE)] = NUL;
4243 if (dfltbutton)
4244 --dfltbutton;
4245
[c2aa910]4246@@ -3493,7 +3495,7 @@
[ba61c16]4247 *msgp++ = (dfltbutton == 1) ? ']' : ')';
4248
4249 /* redefine hotkey */
4250- (void)copy_char(r, hotkp, TRUE);
4251+ hotkp[copy_char(r, hotkp, TRUE)] = NUL;
4252 }
4253 }
4254 else
[c2aa910]4255@@ -3519,8 +3521,6 @@
[ba61c16]4256 *msgp++ = ':';
4257 *msgp++ = ' ';
4258 *msgp = NUL;
4259- mb_ptr_adv(hotkp);
4260- *hotkp = NUL;
4261 }
4262 else
4263 {
[c2aa910]4264@@ -3555,8 +3555,9 @@
[ba61c16]4265 msgp = confirm_msg + 1 + STRLEN(message);
4266 hotkp = hotk;
4267
4268- /* define first default hotkey */
4269- (void)copy_char(buttons, hotkp, TRUE);
4270+ /* Define first default hotkey. Keep the hotkey string NUL
4271+ * terminated to avoid reading past the end. */
4272+ hotkp[copy_char(buttons, hotkp, TRUE)] = NUL;
4273
4274 /* Remember where the choices start, displaying starts here when
4275 * "hotkp" typed at the more prompt. */
4276diff -Naur vim71.orig/src/misc1.c vim71/src/misc1.c
4277--- vim71.orig/src/misc1.c 2007-05-07 12:49:03.000000000 -0700
[c2aa910]4278+++ vim71/src/misc1.c 2007-10-16 14:14:28.000000000 -0700
[ba61c16]4279@@ -90,7 +90,7 @@
4280 */
4281 int
4282 set_indent(size, flags)
4283- int size;
4284+ int size; /* measured in spaces */
4285 int flags;
4286 {
4287 char_u *p;
4288@@ -98,12 +98,14 @@
4289 char_u *oldline;
4290 char_u *s;
4291 int todo;
4292- int ind_len;
4293+ int ind_len; /* measured in characters */
4294 int line_len;
4295 int doit = FALSE;
4296- int ind_done;
4297+ int ind_done = 0; /* measured in spaces */
4298 int tab_pad;
4299 int retval = FALSE;
4300+ int orig_char_len = -1; /* number of initial whitespace chars when
4301+ 'et' and 'pi' are both set */
4302
4303 /*
4304 * First check if there is anything to do and compute the number of
4305@@ -116,8 +118,10 @@
4306 /* Calculate the buffer size for the new indent, and check to see if it
4307 * isn't already set */
4308
4309- /* if 'expandtab' isn't set: use TABs */
4310- if (!curbuf->b_p_et)
4311+ /* if 'expandtab' isn't set: use TABs; if both 'expandtab' and
4312+ * 'preserveindent' are set count the number of characters at the
4313+ * beginning of the line to be copied */
4314+ if (!curbuf->b_p_et || (!(flags & SIN_INSERT) && curbuf->b_p_pi))
4315 {
4316 /* If 'preserveindent' is set then reuse as much as possible of
4317 * the existing indent structure for the new indent */
4318@@ -148,9 +152,14 @@
4319 ++p;
4320 }
4321
4322+ /* Set initial number of whitespace chars to copy if we are
4323+ * preserving indent but expandtab is set */
4324+ if (curbuf->b_p_et)
4325+ orig_char_len = ind_len;
4326+
4327 /* Fill to next tabstop with a tab, if possible */
4328 tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
4329- if (todo >= tab_pad)
4330+ if (todo >= tab_pad && orig_char_len == -1)
4331 {
4332 doit = TRUE;
4333 todo -= tab_pad;
4334@@ -193,13 +202,42 @@
4335 else
4336 p = skipwhite(p);
4337 line_len = (int)STRLEN(p) + 1;
4338- newline = alloc(ind_len + line_len);
4339- if (newline == NULL)
4340- return FALSE;
4341+
4342+ /* If 'preserveindent' and 'expandtab' are both set keep the original
4343+ * characters and allocate accordingly. We will fill the rest with spaces
4344+ * after the if (!curbuf->b_p_et) below. */
4345+ if (orig_char_len != -1)
4346+ {
4347+ newline = alloc(orig_char_len + size - ind_done + line_len);
4348+ if (newline == NULL)
4349+ return FALSE;
4350+ todo = size - ind_done;
4351+ ind_len = orig_char_len + todo; /* Set total length of indent in
4352+ * characters, which may have been
4353+ * undercounted until now */
4354+ p = oldline;
4355+ s = newline;
4356+ while (orig_char_len > 0)
4357+ {
4358+ *s++ = *p++;
4359+ orig_char_len--;
4360+ }
4361+ /* Skip over any additional white space (useful when newindent is less
4362+ * than old) */
4363+ while (vim_iswhite(*p))
4364+ (void)*p++;
4365+
4366+ }
4367+ else
4368+ {
4369+ todo = size;
4370+ newline = alloc(ind_len + line_len);
4371+ if (newline == NULL)
4372+ return FALSE;
4373+ s = newline;
4374+ }
4375
4376 /* Put the characters in the new line. */
4377- s = newline;
4378- todo = size;
4379 /* if 'expandtab' isn't set: use TABs */
4380 if (!curbuf->b_p_et)
4381 {
4382@@ -1320,8 +1358,8 @@
4383 newindent += (int)curbuf->b_p_sw;
4384 }
4385 #endif
4386- /* Copy the indent only if expand tab is disabled */
4387- if (curbuf->b_p_ci && !curbuf->b_p_et)
4388+ /* Copy the indent */
4389+ if (curbuf->b_p_ci)
4390 {
4391 (void)copy_indent(newindent, saved_line);
4392
[c2aa910]4393@@ -3468,9 +3506,38 @@
4394 #endif
4395
4396 /*
4397+ * Call expand_env() and store the result in an allocated string.
4398+ * This is not very memory efficient, this expects the result to be freed
4399+ * again soon.
4400+ */
4401+ char_u *
4402+expand_env_save(src)
4403+ char_u *src;
4404+{
4405+ return expand_env_save_opt(src, FALSE);
4406+}
4407+
4408+/*
4409+ * Idem, but when "one" is TRUE handle the string as one file name, only
4410+ * expand "~" at the start.
4411+ */
4412+ char_u *
4413+expand_env_save_opt(src, one)
4414+ char_u *src;
4415+ int one;
4416+{
4417+ char_u *p;
4418+
4419+ p = alloc(MAXPATHL);
4420+ if (p != NULL)
4421+ expand_env_esc(src, p, MAXPATHL, FALSE, one, NULL);
4422+ return p;
4423+}
4424+
4425+/*
4426 * Expand environment variable with path name.
4427 * "~/" is also expanded, using $HOME. For Unix "~user/" is expanded.
4428- * Skips over "\ ", "\~" and "\$".
4429+ * Skips over "\ ", "\~" and "\$" (not for Win32 though).
4430 * If anything fails no expansion is done and dst equals src.
4431 */
4432 void
4433@@ -3479,15 +3546,16 @@
4434 char_u *dst; /* where to put the result */
4435 int dstlen; /* maximum length of the result */
4436 {
4437- expand_env_esc(src, dst, dstlen, FALSE, NULL);
4438+ expand_env_esc(src, dst, dstlen, FALSE, FALSE, NULL);
4439 }
4440
4441 void
4442-expand_env_esc(srcp, dst, dstlen, esc, startstr)
4443+expand_env_esc(srcp, dst, dstlen, esc, one, startstr)
4444 char_u *srcp; /* input string e.g. "$HOME/vim.hlp" */
4445 char_u *dst; /* where to put the result */
4446 int dstlen; /* maximum length of the result */
4447 int esc; /* escape spaces in expanded variables */
4448+ int one; /* "srcp" is one file name */
4449 char_u *startstr; /* start again after this (can be NULL) */
4450 {
4451 char_u *src;
4452@@ -3728,6 +3796,8 @@
4453 {
4454 /*
4455 * Recognize the start of a new name, for '~'.
4456+ * Don't do this when "one" is TRUE, to avoid expanding "~" in
4457+ * ":edit foo ~ foo".
4458 */
4459 at_start = FALSE;
4460 if (src[0] == '\\' && src[1] != NUL)
4461@@ -3735,7 +3805,7 @@
4462 *dst++ = *src++;
4463 --dstlen;
4464 }
4465- else if (src[0] == ' ' || src[0] == ',')
4466+ else if ((src[0] == ' ' || src[0] == ',') && !one)
4467 at_start = TRUE;
4468 *dst++ = *src++;
4469 --dstlen;
4470@@ -4032,23 +4102,6 @@
4471 }
4472
4473 /*
4474- * Call expand_env() and store the result in an allocated string.
4475- * This is not very memory efficient, this expects the result to be freed
4476- * again soon.
4477- */
4478- char_u *
4479-expand_env_save(src)
4480- char_u *src;
4481-{
4482- char_u *p;
4483-
4484- p = alloc(MAXPATHL);
4485- if (p != NULL)
4486- expand_env(src, p, MAXPATHL);
4487- return p;
4488-}
4489-
4490-/*
4491 * Our portable version of setenv.
4492 */
4493 void
4494@@ -4786,7 +4839,7 @@
[ba61c16]4495 static int cin_iswhileofdo __ARGS((char_u *, linenr_T, int));
4496 static int cin_iswhileofdo_end __ARGS((int terminated, int ind_maxparen, int ind_maxcomment));
4497 static int cin_isbreak __ARGS((char_u *));
4498-static int cin_is_cpp_baseclass __ARGS((char_u *line, colnr_T *col));
4499+static int cin_is_cpp_baseclass __ARGS((colnr_T *col));
4500 static int get_baseclass_amount __ARGS((int col, int ind_maxparen, int ind_maxcomment, int ind_cpp_baseclass));
4501 static int cin_ends_in __ARGS((char_u *, char_u *, char_u *));
4502 static int cin_skip2pos __ARGS((pos_T *trypos));
[c2aa910]4503@@ -5551,13 +5604,13 @@
[ba61c16]4504 * This is a lot of guessing. Watch out for "cond ? func() : foo".
4505 */
4506 static int
4507-cin_is_cpp_baseclass(line, col)
4508- char_u *line;
4509+cin_is_cpp_baseclass(col)
4510 colnr_T *col; /* return: column to align with */
4511 {
4512 char_u *s;
4513 int class_or_struct, lookfor_ctor_init, cpp_base_class;
4514 linenr_T lnum = curwin->w_cursor.lnum;
4515+ char_u *line = ml_get_curline();
4516
4517 *col = 0;
4518
[c2aa910]4519@@ -5585,7 +5638,8 @@
[ba61c16]4520 */
4521 while (lnum > 1)
4522 {
4523- s = skipwhite(ml_get(lnum - 1));
4524+ line = ml_get(lnum - 1);
4525+ s = skipwhite(line);
4526 if (*s == '#' || *s == NUL)
4527 break;
4528 while (*s != NUL)
[c2aa910]4529@@ -5602,7 +5656,8 @@
[ba61c16]4530 --lnum;
4531 }
4532
4533- s = cin_skipcomment(ml_get(lnum));
4534+ line = ml_get(lnum);
4535+ s = cin_skipcomment(line);
4536 for (;;)
4537 {
4538 if (*s == NUL)
[c2aa910]4539@@ -5610,7 +5665,10 @@
[ba61c16]4540 if (lnum == curwin->w_cursor.lnum)
4541 break;
4542 /* Continue in the cursor line. */
4543- s = cin_skipcomment(ml_get(++lnum));
4544+ line = ml_get(++lnum);
4545+ s = cin_skipcomment(line);
4546+ if (*s == NUL)
4547+ continue;
4548 }
4549
4550 if (s[0] == ':')
[c2aa910]4551@@ -7079,7 +7137,7 @@
[ba61c16]4552 n = FALSE;
4553 if (lookfor != LOOKFOR_TERM && ind_cpp_baseclass > 0)
4554 {
4555- n = cin_is_cpp_baseclass(l, &col);
4556+ n = cin_is_cpp_baseclass(&col);
4557 l = ml_get_curline();
4558 }
4559 if (n)
[c2aa910]4560@@ -7670,7 +7728,7 @@
[ba61c16]4561 n = FALSE;
4562 if (ind_cpp_baseclass != 0 && theline[0] != '{')
4563 {
4564- n = cin_is_cpp_baseclass(l, &col);
4565+ n = cin_is_cpp_baseclass(&col);
4566 l = ml_get_curline();
4567 }
4568 if (n)
[c2aa910]4569@@ -8596,7 +8654,7 @@
[ba61c16]4570 for (p = buf + wildoff; p < s; ++p)
4571 if (rem_backslash(p))
4572 {
4573- STRCPY(p, p + 1);
4574+ mch_memmove(p, p + 1, STRLEN(p));
4575 --e;
4576 --s;
4577 }
[c2aa910]4578@@ -8897,7 +8955,7 @@
[ba61c16]4579 for (p = buf + wildoff; p < s; ++p)
4580 if (rem_backslash(p))
4581 {
4582- STRCPY(p, p + 1);
4583+ mch_memmove(p, p + 1, STRLEN(p));
4584 --e;
4585 --s;
4586 }
[c2aa910]4587@@ -9096,7 +9154,7 @@
4588 */
4589 if (vim_strpbrk(p, (char_u *)"$~") != NULL)
4590 {
4591- p = expand_env_save(p);
4592+ p = expand_env_save_opt(p, TRUE);
4593 if (p == NULL)
4594 p = pat[i];
4595 #ifdef UNIX
4596diff -Naur vim71.orig/src/misc2.c vim71/src/misc2.c
4597--- vim71.orig/src/misc2.c 2007-05-07 12:49:26.000000000 -0700
4598+++ vim71/src/misc2.c 2007-10-16 14:14:41.000000000 -0700
4599@@ -972,7 +972,7 @@
4600 return;
4601 entered = TRUE;
4602
4603- ++autocmd_block; /* don't want to trigger autocommands here */
4604+ block_autocmds(); /* don't want to trigger autocommands here */
4605
4606 #ifdef FEAT_WINDOWS
4607 /* close all tabs and windows */
4608@@ -1037,7 +1037,9 @@
4609
4610 /* Free some global vars. */
4611 vim_free(username);
4612+# ifdef FEAT_CLIPBOARD
4613 vim_free(clip_exclude_prog);
4614+# endif
4615 vim_free(last_cmdline);
4616 vim_free(new_last_cmdline);
4617 set_keep_msg(NULL, 0);
[ba61c16]4618diff -Naur vim71.orig/src/normal.c vim71/src/normal.c
4619--- vim71.orig/src/normal.c 2007-05-07 12:34:39.000000000 -0700
[c2aa910]4620+++ vim71/src/normal.c 2007-10-16 14:14:41.000000000 -0700
4621@@ -690,13 +690,20 @@
4622 ca.count0 = ca.count0 * 10 + (c - '0');
4623 if (ca.count0 < 0) /* got too large! */
4624 ca.count0 = 999999999L;
4625+#ifdef FEAT_EVAL
4626+ /* Set v:count here, when called from main() and not a stuffed
4627+ * command, so that v:count can be used in an expression mapping
4628+ * right after the count. */
4629+ if (toplevel && stuff_empty())
4630+ set_vcount(ca.count0, ca.count0 == 0 ? 1 : ca.count0);
4631+#endif
4632 if (ctrl_w)
4633 {
4634 ++no_mapping;
4635 ++allow_keys; /* no mapping for nchar, but keys */
4636 }
4637 ++no_zero_mapping; /* don't map zero here */
4638- c = safe_vgetc();
4639+ c = plain_vgetc();
4640 #ifdef FEAT_LANGMAP
4641 LANGMAP_ADJUST(c, TRUE);
4642 #endif
4643@@ -721,7 +728,7 @@
4644 ca.count0 = 0;
4645 ++no_mapping;
4646 ++allow_keys; /* no mapping for nchar, but keys */
4647- c = safe_vgetc(); /* get next character */
4648+ c = plain_vgetc(); /* get next character */
4649 #ifdef FEAT_LANGMAP
4650 LANGMAP_ADJUST(c, TRUE);
4651 #endif
4652@@ -889,13 +896,18 @@
[ba61c16]4653
4654 ++no_mapping;
4655 ++allow_keys; /* no mapping for nchar, but allow key codes */
4656+#ifdef FEAT_AUTOCMD
4657+ /* Don't generate a CursorHold event here, most commands can't handle
4658+ * it, e.g., nv_replace(), nv_csearch(). */
4659+ did_cursorhold = TRUE;
4660+#endif
4661 if (ca.cmdchar == 'g')
4662 {
4663 /*
[c2aa910]4664 * For 'g' get the next character now, so that we can check for
4665 * "gr", "g'" and "g`".
4666 */
4667- ca.nchar = safe_vgetc();
4668+ ca.nchar = plain_vgetc();
4669 #ifdef FEAT_LANGMAP
4670 LANGMAP_ADJUST(ca.nchar, TRUE);
4671 #endif
4672@@ -952,7 +964,7 @@
4673 im_set_active(TRUE);
4674 #endif
4675
4676- *cp = safe_vgetc();
4677+ *cp = plain_vgetc();
4678
4679 if (langmap_active)
4680 {
4681@@ -1040,7 +1052,7 @@
4682 }
4683 if (c > 0)
4684 {
4685- c = safe_vgetc();
4686+ c = plain_vgetc();
4687 if (c != Ctrl_N && c != Ctrl_G)
4688 vungetc(c);
4689 else
4690@@ -1059,7 +1071,7 @@
4691 while (enc_utf8 && lang && (c = vpeekc()) > 0
4692 && (c >= 0x100 || MB_BYTE2LEN(vpeekc()) > 1))
4693 {
4694- c = safe_vgetc();
4695+ c = plain_vgetc();
4696 if (!utf_iscomposing(c))
4697 {
4698 vungetc(c); /* it wasn't, put it back */
4699@@ -3755,7 +3767,8 @@
[ba61c16]4700 extra_len = (int)STRLEN(p);
4701 overflow = old_len + extra_len - SHOWCMD_COLS;
4702 if (overflow > 0)
4703- STRCPY(showcmd_buf, showcmd_buf + overflow);
4704+ mch_memmove(showcmd_buf, showcmd_buf + overflow,
4705+ old_len - overflow + 1);
4706 STRCAT(showcmd_buf, p);
4707
4708 if (char_avail())
[c2aa910]4709@@ -4558,7 +4571,7 @@
4710 #endif
4711 ++no_mapping;
4712 ++allow_keys; /* no mapping for nchar, but allow key codes */
4713- nchar = safe_vgetc();
4714+ nchar = plain_vgetc();
4715 #ifdef FEAT_LANGMAP
4716 LANGMAP_ADJUST(nchar, TRUE);
4717 #endif
4718@@ -4916,7 +4929,7 @@
4719 case 'u': /* "zug" and "zuw": undo "zg" and "zw" */
4720 ++no_mapping;
4721 ++allow_keys; /* no mapping for nchar, but allow key codes */
4722- nchar = safe_vgetc();
4723+ nchar = plain_vgetc();
4724 #ifdef FEAT_LANGMAP
4725 LANGMAP_ADJUST(nchar, TRUE);
4726 #endif
4727@@ -6379,7 +6392,7 @@
[ba61c16]4728 */
4729 else if (cap->nchar == 'p' || cap->nchar == 'P')
4730 {
4731- if (!checkclearopq(cap->oap))
4732+ if (!checkclearop(cap->oap))
4733 {
4734 prep_redo_cmd(cap);
4735 do_put(cap->oap->regname,
[c2aa910]4736@@ -6662,6 +6675,13 @@
[ba61c16]4737 else
4738 had_ctrl_v = NUL;
4739
4740+ /* Abort if the character is a special key. */
4741+ if (IS_SPECIAL(cap->nchar))
4742+ {
4743+ clearopbeep(cap->oap);
4744+ return;
4745+ }
4746+
4747 #ifdef FEAT_VISUAL
4748 /* Visual mode "r" */
4749 if (VIsual_active)
[c2aa910]4750@@ -6688,11 +6708,9 @@
[ba61c16]4751 }
4752 #endif
4753
4754- /*
4755- * Check for a special key or not enough characters to replace.
4756- */
4757+ /* Abort if not enough characters to replace. */
4758 ptr = ml_get_cursor();
4759- if (IS_SPECIAL(cap->nchar) || STRLEN(ptr) < (unsigned)cap->count1
4760+ if (STRLEN(ptr) < (unsigned)cap->count1
4761 #ifdef FEAT_MBYTE
4762 || (has_mbyte && mb_charlen(ptr) < cap->count1)
4763 #endif
[c2aa910]4764@@ -8353,7 +8371,7 @@
4765 n = fwd_word(cap->count1, cap->arg, cap->oap->op_type != OP_NOP);
4766
4767 /* Don't leave the cursor on the NUL past a line */
4768- if (curwin->w_cursor.col && gchar_cursor() == NUL)
4769+ if (n != FAIL && curwin->w_cursor.col > 0 && gchar_cursor() == NUL)
4770 {
4771 --curwin->w_cursor.col;
4772 cap->oap->inclusive = TRUE;
[ba61c16]4773diff -Naur vim71.orig/src/ops.c vim71/src/ops.c
4774--- vim71.orig/src/ops.c 2007-05-07 12:33:47.000000000 -0700
[c2aa910]4775+++ vim71/src/ops.c 2007-10-16 14:14:28.000000000 -0700
4776@@ -2477,7 +2477,7 @@
4777
4778 /*
4779 * Spaces and tabs in the indent may have changed to other spaces and
4780- * tabs. Get the starting column again and correct the lenght.
4781+ * tabs. Get the starting column again and correct the length.
4782 * Don't do this when "$" used, end-of-line will have changed.
4783 */
4784 block_prep(oap, &bd2, oap->start.lnum, TRUE);
4785@@ -2534,7 +2534,9 @@
4786 #ifdef FEAT_VISUALEXTRA
4787 long offset;
4788 linenr_T linenr;
4789- long ins_len, pre_textlen = 0;
4790+ long ins_len;
4791+ long pre_textlen = 0;
4792+ long pre_indent = 0;
4793 char_u *firstline;
4794 char_u *ins_text, *newp, *oldp;
4795 struct block_def bd;
4796@@ -2579,7 +2581,9 @@
4797 || gchar_cursor() == NUL))
4798 coladvance_force(getviscol());
4799 # endif
4800- pre_textlen = (long)STRLEN(ml_get(oap->start.lnum));
4801+ firstline = ml_get(oap->start.lnum);
4802+ pre_textlen = (long)STRLEN(firstline);
4803+ pre_indent = (long)(skipwhite(firstline) - firstline);
4804 bd.textcol = curwin->w_cursor.col;
4805 }
4806 #endif
4807@@ -2598,13 +2602,22 @@
4808 */
4809 if (oap->block_mode && oap->start.lnum != oap->end.lnum)
4810 {
4811+ /* Auto-indenting may have changed the indent. If the cursor was past
4812+ * the indent, exclude that indent change from the inserted text. */
4813 firstline = ml_get(oap->start.lnum);
4814- /*
4815- * Subsequent calls to ml_get() flush the firstline data - take a
4816- * copy of the required bit.
4817- */
4818- if ((ins_len = (long)STRLEN(firstline) - pre_textlen) > 0)
4819+ if (bd.textcol > (colnr_T)pre_indent)
4820+ {
4821+ long new_indent = (long)(skipwhite(firstline) - firstline);
4822+
4823+ pre_textlen += new_indent - pre_indent;
4824+ bd.textcol += new_indent - pre_indent;
4825+ }
4826+
4827+ ins_len = (long)STRLEN(firstline) - pre_textlen;
4828+ if (ins_len > 0)
4829 {
4830+ /* Subsequent calls to ml_get() flush the firstline data - take a
4831+ * copy of the inserted text. */
4832 if ((ins_text = alloc_check((unsigned)(ins_len + 1))) != NULL)
4833 {
4834 vim_strncpy(ins_text, firstline + bd.textcol, (size_t)ins_len);
4835@@ -3404,7 +3417,9 @@
[ba61c16]4836
4837 #ifdef FEAT_VIRTUALEDIT
4838 col += curwin->w_cursor.coladd;
4839- if (ve_flags == VE_ALL && curwin->w_cursor.coladd > 0)
4840+ if (ve_flags == VE_ALL
4841+ && (curwin->w_cursor.coladd > 0
4842+ || endcol2 == curwin->w_cursor.col))
4843 {
4844 if (dir == FORWARD && c == NUL)
4845 ++col;
4846diff -Naur vim71.orig/src/option.c vim71/src/option.c
4847--- vim71.orig/src/option.c 2007-05-01 04:26:10.000000000 -0700
[c2aa910]4848+++ vim71/src/option.c 2007-10-16 14:14:38.000000000 -0700
4849@@ -427,6 +427,8 @@
4850 #define P_NOGLOB 0x100000L/* do not use local value for global vimrc */
4851 #define P_NFNAME 0x200000L/* only normal file name chars allowed */
4852 #define P_INSECURE 0x400000L/* option was set from a modeline */
4853+#define P_PRI_MKRC 0x800000L/* priority for :mkvimrc (setting option has
4854+ side effects) */
4855
4856 #define ISK_LATIN1 (char_u *)"@,48-57,_,192-255"
4857
4858@@ -773,6 +775,8 @@
4859 {(char_u *)0L, (char_u *)0L}
4860 #endif
4861 },
4862+ /* P_PRI_MKRC isn't needed here, optval_default()
4863+ * always returns TRUE for 'compatible' */
4864 {"compatible", "cp", P_BOOL|P_RALL,
4865 (char_u *)&p_cp, PV_NONE,
4866 {(char_u *)TRUE, (char_u *)FALSE}},
4867@@ -1515,7 +1519,7 @@
4868 {(char_u *)0L, (char_u *)0L}
4869 #endif
4870 },
4871- {"keymap", "kmp", P_STRING|P_ALLOCED|P_VI_DEF|P_RBUF|P_RSTAT|P_NFNAME,
4872+ {"keymap", "kmp", P_STRING|P_ALLOCED|P_VI_DEF|P_RBUF|P_RSTAT|P_NFNAME|P_PRI_MKRC,
4873 #ifdef FEAT_KEYMAP
4874 (char_u *)&p_keymap, PV_KMAP,
4875 {(char_u *)"", (char_u *)0L}
4876@@ -1836,7 +1840,7 @@
4877 {"paragraphs", "para", P_STRING|P_VI_DEF,
4878 (char_u *)&p_para, PV_NONE,
4879 {(char_u *)"IPLPPPQPP LIpplpipbp", (char_u *)0L}},
4880- {"paste", NULL, P_BOOL|P_VI_DEF,
4881+ {"paste", NULL, P_BOOL|P_VI_DEF|P_PRI_MKRC,
4882 (char_u *)&p_paste, PV_NONE,
4883 {(char_u *)FALSE, (char_u *)0L}},
4884 {"pastetoggle", "pt", P_STRING|P_VI_DEF,
4885@@ -4628,7 +4632,7 @@
[ba61c16]4886 if ((!(flags & P_COMMA) || *s != ',')
4887 && vim_strchr(s + 1, *s) != NULL)
4888 {
4889- STRCPY(s, s + 1);
4890+ mch_memmove(s, s + 1, STRLEN(s));
4891 --s;
4892 }
4893 }
[c2aa910]4894@@ -4992,7 +4996,7 @@
4895 * For 'spellsuggest' expand after "file:".
4896 */
4897 expand_env_esc(val, NameBuff, MAXPATHL,
4898- (char_u **)options[opt_idx].var == &p_tags,
4899+ (char_u **)options[opt_idx].var == &p_tags, FALSE,
4900 #ifdef FEAT_SPELL
4901 (char_u **)options[opt_idx].var == &p_sps ? (char_u *)"file:" :
4902 #endif
4903@@ -6348,7 +6352,7 @@
4904 errmsg = check_stl_option(p_ruf);
4905 }
4906 /* check 'statusline' only if it doesn't start with "%!" */
4907- else if (varp != &p_stl || s[0] != '%' || s[1] != '!')
4908+ else if (varp == &p_ruf || s[0] != '%' || s[1] != '!')
4909 errmsg = check_stl_option(s);
4910 if (varp == &p_ruf && errmsg == NULL)
4911 comp_col();
4912@@ -7118,6 +7122,11 @@
[ba61c16]4913 /* when 'endofline' is changed, redraw the window title */
4914 else if ((int *)varp == &curbuf->b_p_eol)
4915 need_maketitle = TRUE;
4916+#ifdef FEAT_MBYTE
4917+ /* when 'bomb' is changed, redraw the window title */
4918+ else if ((int *)varp == &curbuf->b_p_bomb)
4919+ need_maketitle = TRUE;
4920+#endif
4921 #endif
4922
4923 /* when 'bin' is set also set some other options */
[c2aa910]4924@@ -7815,6 +7824,8 @@
4925 errmsg = e_positive;
4926 p_ch = 1;
4927 }
4928+ if (p_ch > Rows - min_rows() + 1)
4929+ p_ch = Rows - min_rows() + 1;
4930
4931 /* Only compute the new window layout when startup has been
4932 * completed. Otherwise the frame sizes may be wrong. */
4933@@ -8219,6 +8230,25 @@
[ba61c16]4934 varp = get_varp(&options[opt_idx]);
4935 if (varp != NULL) /* hidden option is not changed */
4936 {
4937+ if (number == 0 && string != NULL)
4938+ {
4939+ int index;
4940+
4941+ /* Either we are given a string or we are setting option
4942+ * to zero. */
4943+ for (index = 0; string[index] == '0'; ++index)
4944+ ;
4945+ if (string[index] != NUL || index == 0)
4946+ {
4947+ /* There's another character after zeros or the string
4948+ * is empty. In both cases, we are trying to set a
4949+ * num option using a string. */
4950+ EMSG3(_("E521: Number required: &%s = '%s'"),
4951+ name, string);
4952+ return; /* do nothing as we hit an error */
4953+
4954+ }
4955+ }
4956 if (flags & P_NUM)
4957 (void)set_num_option(opt_idx, varp, number,
4958 NULL, 0, opt_flags);
[c2aa910]4959@@ -8511,13 +8541,20 @@
4960 char_u *varp_local = NULL; /* fresh value */
4961 char *cmd;
4962 int round;
4963+ int pri;
4964
4965 /*
4966 * The options that don't have a default (terminal name, columns, lines)
4967 * are never written. Terminal options are also not written.
4968+ * Do the loop over "options[]" twice: once for options with the
4969+ * P_PRI_MKRC flag and once without.
4970 */
4971- for (p = &options[0]; !istermoption(p); p++)
4972- if (!(p->flags & P_NO_MKRC) && !istermoption(p))
4973+ for (pri = 1; pri >= 0; --pri)
4974+ {
4975+ for (p = &options[0]; !istermoption(p); p++)
4976+ if (!(p->flags & P_NO_MKRC)
4977+ && !istermoption(p)
4978+ && ((pri == 1) == ((p->flags & P_PRI_MKRC) != 0)))
4979 {
4980 /* skip global option when only doing locals */
4981 if (p->indir == PV_NONE && !(opt_flags & OPT_GLOBAL))
4982@@ -8613,6 +8650,7 @@
4983 }
4984 }
4985 }
4986+ }
4987 return OK;
4988 }
4989
4990@@ -8715,6 +8753,8 @@
4991 char *name;
4992 int value;
4993 {
4994+ if (value < 0) /* global/local option using global value */
4995+ return OK;
4996 if (fprintf(fd, "%s %s%s", cmd, value ? "" : "no", name) < 0
4997 || put_eol(fd) < 0)
4998 return FAIL;
4999@@ -10585,6 +10625,8 @@
[ba61c16]5000 buf->b_start_ffc = *buf->b_p_ff;
5001 buf->b_start_eol = buf->b_p_eol;
5002 #ifdef FEAT_MBYTE
5003+ buf->b_start_bomb = buf->b_p_bomb;
5004+
5005 /* Only use free/alloc when necessary, they take time. */
5006 if (buf->b_start_fenc == NULL
5007 || STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0)
[c2aa910]5008@@ -10598,13 +10640,17 @@
[ba61c16]5009 /*
5010 * Return TRUE if 'fileformat' and/or 'fileencoding' has a different value
5011 * from when editing started (save_file_ff() called).
5012- * Also when 'endofline' was changed and 'binary' is set.
5013+ * Also when 'endofline' was changed and 'binary' is set, or when 'bomb' was
5014+ * changed and 'binary' is not set.
5015 * Don't consider a new, empty buffer to be changed.
5016 */
5017 int
5018 file_ff_differs(buf)
5019 buf_T *buf;
5020 {
5021+ /* In a buffer that was never loaded the options are not valid. */
5022+ if (buf->b_flags & BF_NEVERLOADED)
5023+ return FALSE;
5024 if ((buf->b_flags & BF_NEW)
5025 && buf->b_ml.ml_line_count == 1
5026 && *ml_get_buf(buf, (linenr_T)1, FALSE) == NUL)
[c2aa910]5027@@ -10614,6 +10660,8 @@
[ba61c16]5028 if (buf->b_p_bin && buf->b_start_eol != buf->b_p_eol)
5029 return TRUE;
5030 #ifdef FEAT_MBYTE
5031+ if (!buf->b_p_bin && buf->b_start_bomb != buf->b_p_bomb)
5032+ return TRUE;
5033 if (buf->b_start_fenc == NULL)
5034 return (*buf->b_p_fenc != NUL);
5035 return (STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0);
5036diff -Naur vim71.orig/src/os_unix.c vim71/src/os_unix.c
5037--- vim71.orig/src/os_unix.c 2007-05-09 12:41:58.000000000 -0700
[c2aa910]5038+++ vim71/src/os_unix.c 2007-10-16 14:14:22.000000000 -0700
[ba61c16]5039@@ -753,7 +753,8 @@
5040 if (signal_stack != NULL)
5041 {
5042 # ifdef HAVE_SIGALTSTACK
5043-# ifdef __APPLE__
5044+# if defined(__APPLE__) && (!defined(MAC_OS_X_VERSION_MAX_ALLOWED) \
5045+ || MAC_OS_X_VERSION_MAX_ALLOWED <= 1040)
5046 /* missing prototype. Adding it to osdef?.h.in doesn't work, because
5047 * "struct sigaltstack" needs to be declared. */
5048 extern int sigaltstack __ARGS((const struct sigaltstack *ss, struct sigaltstack *oss));
5049@@ -2499,7 +2500,13 @@
5050 if (stat((char *)name, &statb))
5051 #endif
5052 return -1;
5053+#ifdef __INTERIX
5054+ /* The top bit makes the value negative, which means the file doesn't
5055+ * exist. Remove the bit, we don't use it. */
5056+ return statb.st_mode & ~S_ADDACE;
5057+#else
5058 return statb.st_mode;
5059+#endif
5060 }
5061
5062 /*
5063@@ -5682,7 +5689,7 @@
5064
5065 /*
5066 * Closes connection to gpm
5067- * returns non-zero if connection succesfully closed
5068+ * returns non-zero if connection successfully closed
5069 */
5070 static void
5071 gpm_close()
5072diff -Naur vim71.orig/src/os_unix.h vim71/src/os_unix.h
5073--- vim71.orig/src/os_unix.h 2007-05-07 12:35:05.000000000 -0700
[c2aa910]5074+++ vim71/src/os_unix.h 2007-10-16 14:14:06.000000000 -0700
[ba61c16]5075@@ -508,6 +508,9 @@
5076 #if !defined(S_ISFIFO) && defined(S_IFIFO)
5077 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
5078 #endif
5079+#if !defined(S_ISCHR) && defined(S_IFCHR)
5080+# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
5081+#endif
5082
5083 /* Note: Some systems need both string.h and strings.h (Savage). However,
5084 * some systems can't handle both, only use string.h in that case. */
5085diff -Naur vim71.orig/src/popupmnu.c vim71/src/popupmnu.c
5086--- vim71.orig/src/popupmnu.c 2007-03-24 13:07:39.000000000 -0700
[c2aa910]5087+++ vim71/src/popupmnu.c 2007-10-16 14:14:09.000000000 -0700
[ba61c16]5088@@ -75,7 +75,6 @@
5089
5090 row = curwin->w_cline_row + W_WINROW(curwin);
5091 height = curwin->w_cline_height;
5092- col = curwin->w_wcol + W_WINCOL(curwin) - curwin->w_leftcol;
5093
5094 if (firstwin->w_p_pvw)
5095 top_clear = firstwin->w_height;
5096@@ -167,6 +166,15 @@
5097 pum_base_width = max_width;
5098 pum_kind_width = kind_width;
5099
5100+ /* Calculate column */
5101+#ifdef FEAT_RIGHTLEFT
5102+ if (curwin->w_p_rl)
5103+ col = W_WINCOL(curwin) + W_WIDTH(curwin) - curwin->w_wcol -
5104+ curwin->w_leftcol - 1;
5105+ else
5106+#endif
5107+ col = W_WINCOL(curwin) + curwin->w_wcol - curwin->w_leftcol;
5108+
5109 /* if there are more items than room we need a scrollbar */
5110 if (pum_height < size)
5111 {
5112@@ -179,11 +187,23 @@
5113 if (def_width < max_width)
5114 def_width = max_width;
5115
5116- if (col < Columns - PUM_DEF_WIDTH || col < Columns - max_width)
5117+ if (((col < Columns - PUM_DEF_WIDTH || col < Columns - max_width)
5118+#ifdef FEAT_RIGHTLEFT
5119+ && !curwin->w_p_rl)
5120+ || (curwin->w_p_rl && (col > PUM_DEF_WIDTH || col > max_width)
5121+#endif
5122+ ))
5123 {
5124 /* align pum column with "col" */
5125 pum_col = col;
5126- pum_width = Columns - pum_col - pum_scrollbar;
5127+
5128+#ifdef FEAT_RIGHTLEFT
5129+ if (curwin->w_p_rl)
5130+ pum_width = pum_col - pum_scrollbar + 1;
5131+ else
5132+#endif
5133+ pum_width = Columns - pum_col - pum_scrollbar;
5134+
5135 if (pum_width > max_width + kind_width + extra_width + 1
5136 && pum_width > PUM_DEF_WIDTH)
5137 {
5138@@ -195,14 +215,24 @@
5139 else if (Columns < def_width)
5140 {
5141 /* not enough room, will use what we have */
5142- pum_col = 0;
5143+#ifdef FEAT_RIGHTLEFT
5144+ if (curwin->w_p_rl)
5145+ pum_col = Columns - 1;
5146+ else
5147+#endif
5148+ pum_col = 0;
5149 pum_width = Columns - 1;
5150 }
5151 else
5152 {
5153 if (max_width > PUM_DEF_WIDTH)
5154 max_width = PUM_DEF_WIDTH; /* truncate */
5155- pum_col = Columns - max_width;
5156+#ifdef FEAT_RIGHTLEFT
5157+ if (curwin->w_p_rl)
5158+ pum_col = max_width - 1;
5159+ else
5160+#endif
5161+ pum_col = Columns - max_width;
5162 pum_width = max_width - pum_scrollbar;
5163 }
5164
5165@@ -255,8 +285,16 @@
5166 attr = (idx == pum_selected) ? attr_select : attr_norm;
5167
5168 /* prepend a space if there is room */
5169- if (pum_col > 0)
5170- screen_putchar(' ', row, pum_col - 1, attr);
5171+#ifdef FEAT_RIGHTLEFT
5172+ if (curwin->w_p_rl)
5173+ {
5174+ if (pum_col < W_WINCOL(curwin) + W_WIDTH(curwin) - 1)
5175+ screen_putchar(' ', row, pum_col + 1, attr);
5176+ }
5177+ else
5178+#endif
5179+ if (pum_col > 0)
5180+ screen_putchar(' ', row, pum_col - 1, attr);
5181
5182 /* Display each entry, use two spaces for a Tab.
5183 * Do this 3 times: For the main text, kind and extra info */
5184@@ -282,26 +320,67 @@
5185 {
5186 /* Display the text that fits or comes before a Tab.
5187 * First convert it to printable characters. */
5188- char_u *st;
5189- int saved = *p;
5190+ char_u *st;
5191+ int saved = *p;
5192
5193 *p = NUL;
5194 st = transstr(s);
5195 *p = saved;
5196- if (st != NULL)
5197+#ifdef FEAT_RIGHTLEFT
5198+ if (curwin->w_p_rl)
5199 {
5200- screen_puts_len(st, (int)STRLEN(st), row, col,
5201+ if (st != NULL)
5202+ {
5203+ char_u *rt = reverse_text(st);
5204+ char_u *rt_saved = rt;
5205+ int len, j;
5206+
5207+ if (rt != NULL)
5208+ {
5209+ len = STRLEN(rt);
5210+ if (len > pum_width)
5211+ {
5212+ for (j = pum_width; j < len; ++j)
5213+ mb_ptr_adv(rt);
5214+ len = pum_width;
5215+ }
5216+ screen_puts_len(rt, len, row,
5217+ col - len + 1, attr);
5218+ vim_free(rt_saved);
5219+ }
5220+ vim_free(st);
5221+ }
5222+ col -= width;
5223+ }
5224+ else
5225+#endif
5226+ {
5227+ if (st != NULL)
5228+ {
5229+ screen_puts_len(st, (int)STRLEN(st), row, col,
5230 attr);
5231- vim_free(st);
5232+ vim_free(st);
5233+ }
5234+ col += width;
5235 }
5236- col += width;
5237
5238 if (*p != TAB)
5239 break;
5240
5241 /* Display two spaces for a Tab. */
5242- screen_puts_len((char_u *)" ", 2, row, col, attr);
5243- col += 2;
5244+#ifdef FEAT_RIGHTLEFT
5245+ if (curwin->w_p_rl)
5246+ {
5247+ screen_puts_len((char_u *)" ", 2, row, col - 1,
5248+ attr);
5249+ col -= 2;
5250+ }
5251+ else
5252+#endif
5253+ {
5254+ screen_puts_len((char_u *)" ", 2, row, col, attr);
5255+ col += 2;
5256+ }
5257 totwidth += 2;
5258 s = NULL; /* start text at next char */
5259 width = 0;
5260@@ -322,17 +401,44 @@
5261 && pum_array[idx].pum_extra == NULL)
5262 || pum_base_width + n >= pum_width)
5263 break;
5264- screen_fill(row, row + 1, col, pum_col + pum_base_width + n,
5265+#ifdef FEAT_RIGHTLEFT
5266+ if (curwin->w_p_rl)
5267+ {
5268+ screen_fill(row, row + 1, pum_col - pum_base_width - n + 1,
5269+ col + 1, ' ', ' ', attr);
5270+ col = pum_col - pum_base_width - n + 1;
5271+ }
5272+ else
5273+#endif
5274+ {
5275+ screen_fill(row, row + 1, col, pum_col + pum_base_width + n,
5276 ' ', ' ', attr);
5277- col = pum_col + pum_base_width + n;
5278+ col = pum_col + pum_base_width + n;
5279+ }
5280 totwidth = pum_base_width + n;
5281 }
5282
5283- screen_fill(row, row + 1, col, pum_col + pum_width, ' ', ' ', attr);
5284+#ifdef FEAT_RIGHTLEFT
5285+ if (curwin->w_p_rl)
5286+ screen_fill(row, row + 1, pum_col - pum_width + 1, col + 1, ' ',
5287+ ' ', attr);
5288+ else
5289+#endif
5290+ screen_fill(row, row + 1, col, pum_col + pum_width, ' ', ' ',
5291+ attr);
5292 if (pum_scrollbar > 0)
5293- screen_putchar(' ', row, pum_col + pum_width,
5294- i >= thumb_pos && i < thumb_pos + thumb_heigth
5295+ {
5296+#ifdef FEAT_RIGHTLEFT
5297+ if (curwin->w_p_rl)
5298+ screen_putchar(' ', row, pum_col - pum_width,
5299+ i >= thumb_pos && i < thumb_pos + thumb_heigth
5300 ? attr_thumb : attr_scroll);
5301+ else
5302+#endif
5303+ screen_putchar(' ', row, pum_col + pum_width,
5304+ i >= thumb_pos && i < thumb_pos + thumb_heigth
5305+ ? attr_thumb : attr_scroll);
5306+ }
5307
5308 ++row;
5309 }
5310@@ -466,7 +572,7 @@
5311 set_option_value((char_u *)"bh", 0L,
5312 (char_u *)"wipe", OPT_LOCAL);
5313 set_option_value((char_u *)"diff", 0L,
5314- (char_u *)"", OPT_LOCAL);
5315+ NULL, OPT_LOCAL);
5316 }
5317 }
5318 if (res == OK)
5319diff -Naur vim71.orig/src/proto/charset.pro vim71/src/proto/charset.pro
5320--- vim71.orig/src/proto/charset.pro 2007-05-12 03:39:01.000000000 -0700
[c2aa910]5321+++ vim71/src/proto/charset.pro 2007-10-16 14:14:20.000000000 -0700
[ba61c16]5322@@ -21,6 +21,7 @@
5323 int vim_iswordp __ARGS((char_u *p));
5324 int vim_iswordc_buf __ARGS((char_u *p, buf_T *buf));
5325 int vim_isfilec __ARGS((int c));
5326+int vim_isfilec_or_wc __ARGS((int c));
5327 int vim_isprintc __ARGS((int c));
5328 int vim_isprintc_strict __ARGS((int c));
5329 int lbr_chartabsize __ARGS((unsigned char *s, colnr_T col));
5330diff -Naur vim71.orig/src/proto/fileio.pro vim71/src/proto/fileio.pro
5331--- vim71.orig/src/proto/fileio.pro 2007-05-12 03:39:14.000000000 -0700
[c2aa910]5332+++ vim71/src/proto/fileio.pro 2007-10-16 14:14:31.000000000 -0700
[ba61c16]5333@@ -2,6 +2,7 @@
5334 void filemess __ARGS((buf_T *buf, char_u *name, char_u *s, int attr));
5335 int readfile __ARGS((char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_skip, linenr_T lines_to_read, exarg_T *eap, int flags));
5336 int prep_exarg __ARGS((exarg_T *eap, buf_T *buf));
5337+int check_file_readonly __ARGS((char_u *fname, int perm));
5338 int buf_write __ARGS((buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_T end, exarg_T *eap, int append, int forceit, int reset_changed, int filtering));
5339 void msg_add_fname __ARGS((buf_T *buf, char_u *fname));
5340 void msg_add_lines __ARGS((int insert_space, long lnum, long nchars));
[c2aa910]5341@@ -39,6 +40,8 @@
5342 int trigger_cursorhold __ARGS((void));
5343 int has_cursormoved __ARGS((void));
5344 int has_cursormovedI __ARGS((void));
5345+void block_autocmds __ARGS((void));
5346+void unblock_autocmds __ARGS((void));
5347 int has_autocmd __ARGS((event_T event, char_u *sfname, buf_T *buf));
5348 char_u *get_augroup_name __ARGS((expand_T *xp, int idx));
5349 char_u *set_context_in_autocmd __ARGS((expand_T *xp, char_u *arg, int doautocmd));
5350diff -Naur vim71.orig/src/proto/getchar.pro vim71/src/proto/getchar.pro
5351--- vim71.orig/src/proto/getchar.pro 2007-05-12 03:39:16.000000000 -0700
5352+++ vim71/src/proto/getchar.pro 2007-10-16 14:14:28.000000000 -0700
5353@@ -38,6 +38,7 @@
5354 void updatescript __ARGS((int c));
5355 int vgetc __ARGS((void));
5356 int safe_vgetc __ARGS((void));
5357+int plain_vgetc __ARGS((void));
5358 int vpeekc __ARGS((void));
5359 int vpeekc_nomap __ARGS((void));
5360 int vpeekc_any __ARGS((void));
5361diff -Naur vim71.orig/src/proto/if_cscope.pro vim71/src/proto/if_cscope.pro
5362--- vim71.orig/src/proto/if_cscope.pro 2007-05-12 03:39:21.000000000 -0700
5363+++ vim71/src/proto/if_cscope.pro 2007-10-16 14:14:28.000000000 -0700
5364@@ -6,4 +6,5 @@
5365 void cs_free_tags __ARGS((void));
5366 void cs_print_tags __ARGS((void));
5367 int cs_connection __ARGS((int num, char_u *dbpath, char_u *ppath));
5368+void cs_end __ARGS((void));
5369 /* vim: set ft=c : */
[ba61c16]5370diff -Naur vim71.orig/src/proto/mbyte.pro vim71/src/proto/mbyte.pro
5371--- vim71.orig/src/proto/mbyte.pro 2007-05-12 03:39:38.000000000 -0700
[c2aa910]5372+++ vim71/src/proto/mbyte.pro 2007-10-16 14:14:28.000000000 -0700
[ba61c16]5373@@ -12,9 +12,9 @@
5374 int utf_ptr2cells __ARGS((char_u *p));
5375 int dbcs_ptr2cells __ARGS((char_u *p));
5376 int latin_char2cells __ARGS((int c));
5377-int latin_off2cells __ARGS((unsigned off));
5378-int dbcs_off2cells __ARGS((unsigned off));
5379-int utf_off2cells __ARGS((unsigned off));
5380+int latin_off2cells __ARGS((unsigned off, unsigned max_off));
5381+int dbcs_off2cells __ARGS((unsigned off, unsigned max_off));
5382+int utf_off2cells __ARGS((unsigned off, unsigned max_off));
5383 int latin_ptr2char __ARGS((char_u *p));
5384 int utf_ptr2char __ARGS((char_u *p));
5385 int mb_ptr2char_adv __ARGS((char_u **pp));
[c2aa910]5386diff -Naur vim71.orig/src/proto/misc1.pro vim71/src/proto/misc1.pro
5387--- vim71.orig/src/proto/misc1.pro 2007-05-12 03:39:34.000000000 -0700
5388+++ vim71/src/proto/misc1.pro 2007-10-16 14:14:28.000000000 -0700
5389@@ -48,10 +48,11 @@
5390 void vim_beep __ARGS((void));
5391 void init_homedir __ARGS((void));
5392 void free_homedir __ARGS((void));
5393+char_u *expand_env_save __ARGS((char_u *src));
5394+char_u *expand_env_save_opt __ARGS((char_u *src, int one));
5395 void expand_env __ARGS((char_u *src, char_u *dst, int dstlen));
5396-void expand_env_esc __ARGS((char_u *srcp, char_u *dst, int dstlen, int esc, char_u *startstr));
5397+void expand_env_esc __ARGS((char_u *srcp, char_u *dst, int dstlen, int esc, int one, char_u *startstr));
5398 char_u *vim_getenv __ARGS((char_u *name, int *mustfree));
5399-char_u *expand_env_save __ARGS((char_u *src));
5400 void vim_setenv __ARGS((char_u *name, char_u *val));
5401 char_u *get_env_name __ARGS((expand_T *xp, int idx));
5402 void home_replace __ARGS((buf_T *buf, char_u *src, char_u *dst, int dstlen, int one));
[ba61c16]5403diff -Naur vim71.orig/src/proto/search.pro vim71/src/proto/search.pro
5404--- vim71.orig/src/proto/search.pro 2007-05-12 03:39:50.000000000 -0700
[c2aa910]5405+++ vim71/src/proto/search.pro 2007-10-16 14:14:09.000000000 -0700
[ba61c16]5406@@ -1,6 +1,7 @@
5407 /* search.c */
5408 int search_regcomp __ARGS((char_u *pat, int pat_save, int pat_use, int options, regmmatch_T *regmatch));
5409 char_u *get_search_pat __ARGS((void));
5410+char_u *reverse_text __ARGS((char_u *s));
5411 void save_search_patterns __ARGS((void));
5412 void restore_search_patterns __ARGS((void));
5413 void free_search_patterns __ARGS((void));
5414diff -Naur vim71.orig/src/proto/syntax.pro vim71/src/proto/syntax.pro
5415--- vim71.orig/src/proto/syntax.pro 2007-05-12 03:39:52.000000000 -0700
[c2aa910]5416+++ vim71/src/proto/syntax.pro 2007-10-16 14:14:07.000000000 -0700
[ba61c16]5417@@ -8,6 +8,8 @@
5418 void syntax_clear __ARGS((buf_T *buf));
5419 void ex_syntax __ARGS((exarg_T *eap));
5420 int syntax_present __ARGS((buf_T *buf));
5421+void reset_expand_highlight __ARGS((void));
5422+void set_context_in_echohl_cmd __ARGS((expand_T *xp, char_u *arg));
5423 void set_context_in_syntax_cmd __ARGS((expand_T *xp, char_u *arg));
5424 char_u *get_syntax_name __ARGS((expand_T *xp, int idx));
5425 int syn_get_id __ARGS((win_T *wp, long lnum, colnr_T col, int trans, int *spellp));
5426diff -Naur vim71.orig/src/proto/window.pro vim71/src/proto/window.pro
5427--- vim71.orig/src/proto/window.pro 2007-05-12 03:40:00.000000000 -0700
[c2aa910]5428+++ vim71/src/proto/window.pro 2007-10-16 14:14:07.000000000 -0700
[ba61c16]5429@@ -59,4 +59,8 @@
5430 int only_one_window __ARGS((void));
5431 void check_lnums __ARGS((int do_curwin));
5432 int win_hasvertsplit __ARGS((void));
5433+int match_add __ARGS((win_T *wp, char_u *grp, char_u *pat, int prio, int id));
5434+int match_delete __ARGS((win_T *wp, int id, int perr));
5435+void clear_matches __ARGS((win_T *wp));
5436+matchitem_T *get_match __ARGS((win_T *wp, int id));
5437 /* vim: set ft=c : */
5438diff -Naur vim71.orig/src/quickfix.c vim71/src/quickfix.c
5439--- vim71.orig/src/quickfix.c 2007-02-03 16:50:17.000000000 -0800
[c2aa910]5440+++ vim71/src/quickfix.c 2007-10-16 14:14:28.000000000 -0700
5441@@ -1612,8 +1612,8 @@
5442 }
5443
5444 /*
5445- * If there is only one window and is the quickfix window, create a new
5446- * one above the quickfix window.
5447+ * If there is only one window and it is the quickfix window, create a
5448+ * new one above the quickfix window.
5449 */
5450 if (((firstwin == lastwin) && bt_quickfix(curbuf)) || !usable_win)
5451 {
[ba61c16]5452@@ -2331,7 +2331,7 @@
5453 set_option_value((char_u *)"bt", 0L, (char_u *)"quickfix",
5454 OPT_LOCAL);
5455 set_option_value((char_u *)"bh", 0L, (char_u *)"wipe", OPT_LOCAL);
5456- set_option_value((char_u *)"diff", 0L, (char_u *)"", OPT_LOCAL);
5457+ set_option_value((char_u *)"diff", 0L, NULL, OPT_LOCAL);
5458 }
5459
5460 /* Only set the height when still in the same tab page and there is no
[c2aa910]5461@@ -2981,6 +2981,7 @@
5462 buf_T *buf;
5463 int duplicate_name = FALSE;
5464 int using_dummy;
5465+ int redraw_for_dummy = FALSE;
5466 int found_match;
5467 buf_T *first_match_buf = NULL;
5468 time_t seconds = 0;
5469@@ -3097,6 +3098,7 @@
5470 /* Remember that a buffer with this name already exists. */
5471 duplicate_name = (buf != NULL);
5472 using_dummy = TRUE;
5473+ redraw_for_dummy = TRUE;
5474
5475 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
5476 /* Don't do Filetype autocommands to avoid loading syntax and
5477@@ -3243,11 +3245,29 @@
5478 if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
5479 {
5480 if ((flags & VGR_NOJUMP) == 0)
5481+ {
5482+ buf = curbuf;
5483 qf_jump(qi, 0, 0, eap->forceit);
5484+ if (buf != curbuf)
5485+ /* If we jumped to another buffer redrawing will already be
5486+ * taken care of. */
5487+ redraw_for_dummy = FALSE;
5488+ }
5489 }
5490 else
5491 EMSG2(_(e_nomatch2), s);
5492
5493+ /* If we loaded a dummy buffer into the current window, the autocommands
5494+ * may have messed up things, need to redraw and recompute folds. */
5495+ if (redraw_for_dummy)
5496+ {
5497+#ifdef FEAT_FOLDING
5498+ foldUpdateAll(curwin);
5499+#else
5500+ redraw_later(NOT_VALID);
5501+#endif
5502+ }
5503+
5504 theend:
5505 vim_free(regmatch.regprog);
5506 }
[ba61c16]5507diff -Naur vim71.orig/src/regexp.c vim71/src/regexp.c
5508--- vim71.orig/src/regexp.c 2007-05-07 12:50:03.000000000 -0700
[c2aa910]5509+++ vim71/src/regexp.c 2007-10-16 14:14:09.000000000 -0700
[ba61c16]5510@@ -2220,7 +2220,7 @@
5511 break;
5512 case CLASS_LOWER:
5513 for (cu = 1; cu <= 255; cu++)
5514- if (islower(cu))
5515+ if (MB_ISLOWER(cu))
5516 regc(cu);
5517 break;
5518 case CLASS_PRINT:
5519@@ -2240,7 +2240,7 @@
5520 break;
5521 case CLASS_UPPER:
5522 for (cu = 1; cu <= 255; cu++)
5523- if (isupper(cu))
5524+ if (MB_ISUPPER(cu))
5525 regc(cu);
5526 break;
5527 case CLASS_XDIGIT:
5528@@ -3465,7 +3465,7 @@
5529 (enc_utf8 && utf_fold(prog->regstart) == utf_fold(c)))
5530 || (c < 255 && prog->regstart < 255 &&
5531 #endif
5532- TOLOWER_LOC(prog->regstart) == TOLOWER_LOC(c)))))
5533+ MB_TOLOWER(prog->regstart) == MB_TOLOWER(c)))))
5534 retval = regtry(prog, col);
5535 else
5536 retval = 0;
5537@@ -4200,7 +4200,7 @@
5538 #ifdef FEAT_MBYTE
5539 !enc_utf8 &&
5540 #endif
5541- TOLOWER_LOC(*opnd) != TOLOWER_LOC(*reginput))))
5542+ MB_TOLOWER(*opnd) != MB_TOLOWER(*reginput))))
5543 status = RA_NOMATCH;
5544 else if (*opnd == NUL)
5545 {
5546@@ -4733,10 +4733,10 @@
5547 rst.nextb = *OPERAND(next);
5548 if (ireg_ic)
5549 {
5550- if (isupper(rst.nextb))
5551- rst.nextb_ic = TOLOWER_LOC(rst.nextb);
5552+ if (MB_ISUPPER(rst.nextb))
5553+ rst.nextb_ic = MB_TOLOWER(rst.nextb);
5554 else
5555- rst.nextb_ic = TOUPPER_LOC(rst.nextb);
5556+ rst.nextb_ic = MB_TOUPPER(rst.nextb);
5557 }
5558 else
5559 rst.nextb_ic = rst.nextb;
5560@@ -5558,11 +5558,12 @@
5561 int cu, cl;
5562
5563 /* This doesn't do a multi-byte character, because a MULTIBYTECODE
5564- * would have been used for it. */
5565+ * would have been used for it. It does handle single-byte
5566+ * characters, such as latin1. */
5567 if (ireg_ic)
5568 {
5569- cu = TOUPPER_LOC(*opnd);
5570- cl = TOLOWER_LOC(*opnd);
5571+ cu = MB_TOUPPER(*opnd);
5572+ cl = MB_TOLOWER(*opnd);
5573 while (count < maxcount && (*scan == cu || *scan == cl))
5574 {
5575 count++;
5576@@ -6490,10 +6491,10 @@
5577 cc = utf_fold(c);
5578 else
5579 #endif
5580- if (isupper(c))
5581- cc = TOLOWER_LOC(c);
5582- else if (islower(c))
5583- cc = TOUPPER_LOC(c);
5584+ if (MB_ISUPPER(c))
5585+ cc = MB_TOLOWER(c);
5586+ else if (MB_ISLOWER(c))
5587+ cc = MB_TOUPPER(c);
5588 else
5589 return vim_strchr(s, c);
5590
5591@@ -6637,9 +6638,9 @@
5592 }
5593 }
5594 else if (magic)
5595- STRCPY(p, p + 1); /* remove '~' */
5596+ mch_memmove(p, p + 1, STRLEN(p)); /* remove '~' */
5597 else
5598- STRCPY(p, p + 2); /* remove '\~' */
5599+ mch_memmove(p, p + 2, STRLEN(p) - 1); /* remove '\~' */
5600 --p;
5601 }
5602 else
5603@@ -7014,7 +7015,14 @@
5604 #ifdef FEAT_MBYTE
5605 if (has_mbyte)
5606 {
5607- int l = mb_ptr2len(s) - 1;
5608+ int l;
5609+
5610+ /* Copy composing characters separately, one
5611+ * at a time. */
5612+ if (enc_utf8)
5613+ l = utf_ptr2len(s) - 1;
5614+ else
5615+ l = mb_ptr2len(s) - 1;
5616
5617 s += l;
5618 len -= l;
5619diff -Naur vim71.orig/src/screen.c vim71/src/screen.c
5620--- vim71.orig/src/screen.c 2007-05-07 12:27:53.000000000 -0700
[c2aa910]5621+++ vim71/src/screen.c 2007-10-16 14:14:28.000000000 -0700
[ba61c16]5622@@ -100,27 +100,7 @@
5623 static int screen_cur_row, screen_cur_col; /* last known cursor position */
5624
5625 #ifdef FEAT_SEARCH_EXTRA
5626-/*
5627- * Struct used for highlighting 'hlsearch' matches for the last use search
5628- * pattern or a ":match" item.
5629- * For 'hlsearch' there is one pattern for all windows. For ":match" there is
5630- * a different pattern for each window.
5631- */
5632-typedef struct
5633-{
5634- regmmatch_T rm; /* points to the regexp program; contains last found
5635- match (may continue in next line) */
5636- buf_T *buf; /* the buffer to search for a match */
5637- linenr_T lnum; /* the line to search for a match */
5638- int attr; /* attributes to be used for a match */
5639- int attr_cur; /* attributes currently active in win_line() */
5640- linenr_T first_lnum; /* first lnum to search for multi-line pat */
5641- colnr_T startcol; /* in win_line() points to char where HL starts */
5642- colnr_T endcol; /* in win_line() points to char where HL ends */
5643-} match_T;
5644-
5645 static match_T search_hl; /* used for 'hlsearch' highlight matching */
5646-static match_T match_hl[3]; /* used for ":match" highlight matching */
5647 #endif
5648
5649 #ifdef FEAT_FOLDING
5650@@ -155,6 +135,7 @@
5651 static void redraw_custum_statusline __ARGS((win_T *wp));
5652 #endif
5653 #ifdef FEAT_SEARCH_EXTRA
5654+#define SEARCH_HL_PRIORITY 0
5655 static void start_search_hl __ARGS((void));
5656 static void end_search_hl __ARGS((void));
5657 static void prepare_search_hl __ARGS((win_T *wp, linenr_T lnum));
5658@@ -350,6 +331,11 @@
5659 {
5660 if (type < must_redraw) /* use maximal type */
5661 type = must_redraw;
5662+
5663+ /* must_redraw is reset here, so that when we run into some weird
5664+ * reason to redraw while busy redrawing (e.g., asynchronous
5665+ * scrolling), or update_topline() in win_update() will cause a
5666+ * scroll, the screen will be redrawn later or in win_update(). */
5667 must_redraw = 0;
5668 }
5669
5670@@ -787,6 +773,7 @@
5671 w_topline got smaller a bit */
5672 #endif
5673 #ifdef FEAT_SEARCH_EXTRA
5674+ matchitem_T *cur; /* points to the match list */
5675 int top_to_mod = FALSE; /* redraw above mod_top */
5676 #endif
5677
5678@@ -848,18 +835,20 @@
5679 #endif
5680
5681 #ifdef FEAT_SEARCH_EXTRA
5682- /* Setup for ":match" and 'hlsearch' highlighting. Disable any previous
5683+ /* Setup for match and 'hlsearch' highlighting. Disable any previous
5684 * match */
5685- for (i = 0; i < 3; ++i)
5686+ cur = wp->w_match_head;
5687+ while (cur != NULL)
5688 {
5689- match_hl[i].rm = wp->w_match[i];
5690- if (wp->w_match_id[i] == 0)
5691- match_hl[i].attr = 0;
5692- else
5693- match_hl[i].attr = syn_id2attr(wp->w_match_id[i]);
5694- match_hl[i].buf = buf;
5695- match_hl[i].lnum = 0;
5696- match_hl[i].first_lnum = 0;
5697+ cur->hl.rm = cur->match;
5698+ if (cur->hlg_id == 0)
5699+ cur->hl.attr = 0;
5700+ else
5701+ cur->hl.attr = syn_id2attr(cur->hlg_id);
5702+ cur->hl.buf = buf;
5703+ cur->hl.lnum = 0;
5704+ cur->hl.first_lnum = 0;
5705+ cur = cur->next;
5706 }
5707 search_hl.buf = buf;
5708 search_hl.lnum = 0;
5709@@ -923,19 +912,25 @@
5710 * change in one line may make the Search highlighting in a
5711 * previous line invalid. Simple solution: redraw all visible
5712 * lines above the change.
5713- * Same for a ":match" pattern.
5714+ * Same for a match pattern.
5715 */
5716 if (search_hl.rm.regprog != NULL
5717 && re_multiline(search_hl.rm.regprog))
5718 top_to_mod = TRUE;
5719 else
5720- for (i = 0; i < 3; ++i)
5721- if (match_hl[i].rm.regprog != NULL
5722- && re_multiline(match_hl[i].rm.regprog))
5723+ {
5724+ cur = wp->w_match_head;
5725+ while (cur != NULL)
5726+ {
5727+ if (cur->match.regprog != NULL
5728+ && re_multiline(cur->match.regprog))
5729 {
5730 top_to_mod = TRUE;
5731 break;
5732 }
5733+ cur = cur->next;
5734+ }
5735+ }
5736 #endif
5737 }
5738 #ifdef FEAT_FOLDING
5739@@ -1029,6 +1024,13 @@
5740 type = VALID;
5741 }
5742
5743+ /* Trick: we want to avoid clearing the screen twice. screenclear() will
5744+ * set "screen_cleared" to TRUE. The special value MAYBE (which is still
5745+ * non-zero and thus not FALSE) will indicate that screenclear() was not
5746+ * called. */
5747+ if (screen_cleared)
5748+ screen_cleared = MAYBE;
5749+
5750 /*
5751 * If there are no changes on the screen that require a complete redraw,
5752 * handle three cases:
5753@@ -1230,7 +1232,11 @@
5754 mid_end = wp->w_height;
5755 if (lastwin == firstwin)
5756 {
5757- screenclear();
5758+ /* Clear the screen when it was not done by win_del_lines() or
5759+ * win_ins_lines() above, "screen_cleared" is FALSE or MAYBE
5760+ * then. */
5761+ if (screen_cleared != TRUE)
5762+ screenclear();
5763 #ifdef FEAT_WINDOWS
5764 /* The screen was cleared, redraw the tab pages line. */
5765 if (redraw_tabline)
5766@@ -1238,6 +1244,13 @@
5767 #endif
5768 }
5769 }
5770+
5771+ /* When win_del_lines() or win_ins_lines() caused the screen to be
5772+ * cleared (only happens for the first window) or when screenclear()
5773+ * was called directly above, "must_redraw" will have been set to
5774+ * NOT_VALID, need to reset it here to avoid redrawing twice. */
5775+ if (screen_cleared == TRUE)
5776+ must_redraw = 0;
5777 }
5778 else
5779 {
[c2aa910]5780@@ -2292,9 +2305,11 @@
5781 prev_c = u8c;
5782 #endif
5783 /* Non-BMP character: display as ? or fullwidth ?. */
5784+#ifdef UNICODE16
5785 if (u8c >= 0x10000)
5786 ScreenLinesUC[idx] = (cells == 2) ? 0xff1f : (int)'?';
5787 else
5788+#endif
5789 ScreenLinesUC[idx] = u8c;
5790 for (i = 0; i < Screen_mco; ++i)
5791 {
5792@@ -2542,7 +2557,7 @@
[ba61c16]5793
5794 char_u extra[18]; /* "%ld" and 'fdc' must fit in here */
5795 int n_extra = 0; /* number of extra chars */
5796- char_u *p_extra = NULL; /* string of extra chars */
5797+ char_u *p_extra = NULL; /* string of extra chars, plus NUL */
5798 int c_extra = NUL; /* extra chars, all the same */
5799 int extra_attr = 0; /* attributes when n_extra != 0 */
5800 static char_u *at_end_str = (char_u *)""; /* used for p_extra when
[c2aa910]5801@@ -2626,10 +2641,13 @@
[ba61c16]5802 int line_attr = 0; /* atrribute for the whole line */
5803 #endif
5804 #ifdef FEAT_SEARCH_EXTRA
5805- match_T *shl; /* points to search_hl or match_hl */
5806-#endif
5807-#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_MBYTE)
5808- int i;
5809+ matchitem_T *cur; /* points to the match list */
5810+ match_T *shl; /* points to search_hl or a match */
5811+ int shl_flag; /* flag to indicate whether search_hl
5812+ has been processed or not */
5813+ int prevcol_hl_flag; /* flag to indicate whether prevcol
5814+ equals startcol of search_hl or one
5815+ of the matches */
5816 #endif
5817 #ifdef FEAT_ARABIC
5818 int prev_c = 0; /* previous Arabic character */
[c2aa910]5819@@ -3074,12 +3092,20 @@
[ba61c16]5820
5821 #ifdef FEAT_SEARCH_EXTRA
5822 /*
5823- * Handle highlighting the last used search pattern and ":match".
5824- * Do this for both search_hl and match_hl[3].
5825+ * Handle highlighting the last used search pattern and matches.
5826+ * Do this for both search_hl and the match list.
5827 */
5828- for (i = 3; i >= 0; --i)
5829+ cur = wp->w_match_head;
5830+ shl_flag = FALSE;
5831+ while (cur != NULL || shl_flag == FALSE)
5832 {
5833- shl = (i == 3) ? &search_hl : &match_hl[i];
5834+ if (shl_flag == FALSE)
5835+ {
5836+ shl = &search_hl;
5837+ shl_flag = TRUE;
5838+ }
5839+ else
5840+ shl = &cur->hl;
5841 shl->startcol = MAXCOL;
5842 shl->endcol = MAXCOL;
5843 shl->attr_cur = 0;
[c2aa910]5844@@ -3122,6 +3148,8 @@
[ba61c16]5845 area_highlighting = TRUE;
5846 }
5847 }
5848+ if (shl != &search_hl && cur != NULL)
5849+ cur = cur->next;
5850 }
5851 #endif
5852
[c2aa910]5853@@ -3163,10 +3191,8 @@
[ba61c16]5854 if (cmdwin_type != 0 && wp == curwin)
5855 {
5856 /* Draw the cmdline character. */
5857- *extra = cmdwin_type;
5858 n_extra = 1;
5859- p_extra = extra;
5860- c_extra = NUL;
5861+ c_extra = cmdwin_type;
5862 char_attr = hl_attr(HLF_AT);
5863 }
5864 }
[c2aa910]5865@@ -3182,6 +3208,7 @@
[ba61c16]5866 fill_foldcolumn(extra, wp, FALSE, lnum);
5867 n_extra = wp->w_p_fdc;
5868 p_extra = extra;
5869+ p_extra[n_extra] = NUL;
5870 c_extra = NUL;
5871 char_attr = hl_attr(HLF_FC);
5872 }
[c2aa910]5873@@ -3388,13 +3415,24 @@
[ba61c16]5874 * After end, check for start/end of next match.
5875 * When another match, have to check for start again.
5876 * Watch out for matching an empty string!
5877- * Do this first for search_hl, then for match_hl, so that
5878- * ":match" overrules 'hlsearch'.
5879+ * Do this for 'search_hl' and the match list (ordered by
5880+ * priority).
5881 */
5882 v = (long)(ptr - line);
5883- for (i = 3; i >= 0; --i)
5884- {
5885- shl = (i == 3) ? &search_hl : &match_hl[i];
5886+ cur = wp->w_match_head;
5887+ shl_flag = FALSE;
5888+ while (cur != NULL || shl_flag == FALSE)
5889+ {
5890+ if (shl_flag == FALSE
5891+ && ((cur != NULL
5892+ && cur->priority > SEARCH_HL_PRIORITY)
5893+ || cur == NULL))
5894+ {
5895+ shl = &search_hl;
5896+ shl_flag = TRUE;
5897+ }
5898+ else
5899+ shl = &cur->hl;
5900 while (shl->rm.regprog != NULL)
5901 {
5902 if (shl->startcol != MAXCOL
[c2aa910]5903@@ -3442,26 +3480,43 @@
[ba61c16]5904 }
5905 break;
5906 }
5907+ if (shl != &search_hl && cur != NULL)
5908+ cur = cur->next;
5909 }
5910
5911- /* ":match" highlighting overrules 'hlsearch' */
5912- for (i = 0; i <= 3; ++i)
5913- if (i == 3)
5914- search_attr = search_hl.attr_cur;
5915- else if (match_hl[i].attr_cur != 0)
5916+ /* Use attributes from match with highest priority among
5917+ * 'search_hl' and the match list. */
5918+ search_attr = search_hl.attr_cur;
5919+ cur = wp->w_match_head;
5920+ shl_flag = FALSE;
5921+ while (cur != NULL || shl_flag == FALSE)
5922+ {
5923+ if (shl_flag == FALSE
5924+ && ((cur != NULL
5925+ && cur->priority > SEARCH_HL_PRIORITY)
5926+ || cur == NULL))
5927 {
5928- search_attr = match_hl[i].attr_cur;
5929- break;
5930+ shl = &search_hl;
5931+ shl_flag = TRUE;
5932 }
5933+ else
5934+ shl = &cur->hl;
5935+ if (shl->attr_cur != 0)
5936+ search_attr = shl->attr_cur;
5937+ if (shl != &search_hl && cur != NULL)
5938+ cur = cur->next;
5939+ }
5940 }
5941 #endif
5942
5943 #ifdef FEAT_DIFF
5944 if (diff_hlf != (hlf_T)0)
5945 {
5946- if (diff_hlf == HLF_CHD && ptr - line >= change_start)
5947+ if (diff_hlf == HLF_CHD && ptr - line >= change_start
5948+ && n_extra == 0)
5949 diff_hlf = HLF_TXD; /* changed text */
5950- if (diff_hlf == HLF_TXD && ptr - line > change_end)
5951+ if (diff_hlf == HLF_TXD && ptr - line > change_end
5952+ && n_extra == 0)
5953 diff_hlf = HLF_CHD; /* changed line */
5954 line_attr = hl_attr(diff_hlf);
5955 }
[c2aa910]5956@@ -3496,9 +3551,11 @@
[ba61c16]5957 * Get the next character to put on the screen.
5958 */
5959 /*
5960- * The 'extra' array contains the extra stuff that is inserted to
5961- * represent special characters (non-printable stuff). When all
5962- * characters are the same, c_extra is used.
5963+ * The "p_extra" points to the extra stuff that is inserted to
5964+ * represent special characters (non-printable stuff) and other
5965+ * things. When all characters are the same, c_extra is used.
5966+ * "p_extra" must end in a NUL to avoid mb_ptr2len() reads past
5967+ * "p_extra[n_extra]".
5968 * For the '$' of the 'list' option, n_extra == 1, p_extra == "".
5969 */
5970 if (n_extra > 0)
[c2aa910]5971@@ -3611,6 +3668,8 @@
[ba61c16]5972 * Draw it as a space with a composing char. */
5973 if (utf_iscomposing(mb_c))
5974 {
5975+ int i;
5976+
5977 for (i = Screen_mco - 1; i > 0; --i)
5978 u8cc[i] = u8cc[i - 1];
5979 u8cc[0] = mb_c;
[c2aa910]5980@@ -3621,13 +3680,18 @@
5981 if ((mb_l == 1 && c >= 0x80)
5982 || (mb_l >= 1 && mb_c == 0)
5983 || (mb_l > 1 && (!vim_isprintc(mb_c)
5984- || mb_c >= 0x10000)))
5985+# ifdef UNICODE16
5986+ || mb_c >= 0x10000
5987+# endif
5988+ )))
5989 {
5990 /*
5991 * Illegal UTF-8 byte: display as <xx>.
5992 * Non-BMP character : display as ? or fullwidth ?.
5993 */
5994+# ifdef UNICODE16
5995 if (mb_c < 0x10000)
5996+# endif
5997 {
5998 transchar_hex(extra, mb_c);
5999 # ifdef FEAT_RIGHTLEFT
6000@@ -3635,11 +3699,13 @@
6001 rl_mirror(extra);
6002 # endif
6003 }
6004+# ifdef UNICODE16
6005 else if (utf_char2cells(mb_c) != 2)
6006 STRCPY(extra, "?");
6007 else
6008 /* 0xff1f in UTF-8: full-width '?' */
6009 STRCPY(extra, "\357\274\237");
6010+# endif
6011
6012 p_extra = extra;
6013 c = *p_extra;
6014@@ -3752,10 +3818,8 @@
[ba61c16]6015 * a '<' in the first column. */
6016 if (n_skip > 0 && mb_l > 1)
6017 {
6018- extra[0] = '<';
6019- p_extra = extra;
6020 n_extra = 1;
6021- c_extra = NUL;
6022+ c_extra = '<';
6023 c = ' ';
6024 if (area_attr == 0 && search_attr == 0)
6025 {
[c2aa910]6026@@ -4254,14 +4318,29 @@
[ba61c16]6027 * highlight match at end of line. If it's beyond the last
6028 * char on the screen, just overwrite that one (tricky!) Not
6029 * needed when a '$' was displayed for 'list'. */
6030+#ifdef FEAT_SEARCH_EXTRA
6031+ prevcol_hl_flag = FALSE;
6032+ if (prevcol == (long)search_hl.startcol)
6033+ prevcol_hl_flag = TRUE;
6034+ else
6035+ {
6036+ cur = wp->w_match_head;
6037+ while (cur != NULL)
6038+ {
6039+ if (prevcol == (long)cur->hl.startcol)
6040+ {
6041+ prevcol_hl_flag = TRUE;
6042+ break;
6043+ }
6044+ cur = cur->next;
6045+ }
6046+ }
6047+#endif
6048 if (lcs_eol == lcs_eol_one
6049 && ((area_attr != 0 && vcol == fromcol && c == NUL)
6050 #ifdef FEAT_SEARCH_EXTRA
6051 /* highlight 'hlsearch' match at end of line */
6052- || ((prevcol == (long)search_hl.startcol
6053- || prevcol == (long)match_hl[0].startcol
6054- || prevcol == (long)match_hl[1].startcol
6055- || prevcol == (long)match_hl[2].startcol)
6056+ || (prevcol_hl_flag == TRUE
6057 # if defined(LINE_ATTR)
6058 && did_line_attr <= 1
6059 # endif
[c2aa910]6060@@ -4302,15 +4381,27 @@
[ba61c16]6061 #ifdef FEAT_SEARCH_EXTRA
6062 if (area_attr == 0)
6063 {
6064- for (i = 0; i <= 3; ++i)
6065- {
6066- if (i == 3)
6067- char_attr = search_hl.attr;
6068- else if ((ptr - line) - 1 == (long)match_hl[i].startcol)
6069+ /* Use attributes from match with highest priority among
6070+ * 'search_hl' and the match list. */
6071+ char_attr = search_hl.attr;
6072+ cur = wp->w_match_head;
6073+ shl_flag = FALSE;
6074+ while (cur != NULL || shl_flag == FALSE)
6075+ {
6076+ if (shl_flag == FALSE
6077+ && ((cur != NULL
6078+ && cur->priority > SEARCH_HL_PRIORITY)
6079+ || cur == NULL))
6080 {
6081- char_attr = match_hl[i].attr;
6082- break;
6083+ shl = &search_hl;
6084+ shl_flag = TRUE;
6085 }
6086+ else
6087+ shl = &cur->hl;
6088+ if ((ptr - line) - 1 == (long)shl->startcol)
6089+ char_attr = shl->attr;
6090+ if (shl != &search_hl && cur != NULL)
6091+ cur = cur->next;
6092 }
6093 }
6094 #endif
[c2aa910]6095@@ -4460,6 +4551,8 @@
[ba61c16]6096 {
6097 if (mb_utf8)
6098 {
6099+ int i;
6100+
6101 ScreenLinesUC[off] = mb_c;
6102 if ((c & 0xff) == 0)
6103 ScreenLines[off] = 0x80; /* avoid storing zero */
[c2aa910]6104@@ -4548,7 +4641,7 @@
[ba61c16]6105
6106 /*
6107 * At end of screen line and there is more to come: Display the line
6108- * so far. If there is no more to display it is catched above.
6109+ * so far. If there is no more to display it is caught above.
6110 */
6111 if ((
6112 #ifdef FEAT_RIGHTLEFT
[c2aa910]6113@@ -4625,9 +4718,13 @@
[ba61c16]6114 #endif
6115 #ifdef FEAT_MBYTE
6116 && !(has_mbyte
6117- && ((*mb_off2cells)(LineOffset[screen_row]) == 2
6118+ && ((*mb_off2cells)(LineOffset[screen_row],
6119+ LineOffset[screen_row] + screen_Columns)
6120+ == 2
6121 || (*mb_off2cells)(LineOffset[screen_row - 1]
6122- + (int)Columns - 2) == 2))
6123+ + (int)Columns - 2,
6124+ LineOffset[screen_row] + screen_Columns)
6125+ == 2))
6126 #endif
6127 )
6128 {
[c2aa910]6129@@ -4787,6 +4884,10 @@
[ba61c16]6130 {
6131 unsigned off_from;
6132 unsigned off_to;
6133+#ifdef FEAT_MBYTE
6134+ unsigned max_off_from;
6135+ unsigned max_off_to;
6136+#endif
6137 int col = 0;
6138 #if defined(FEAT_GUI) || defined(UNIX) || defined(FEAT_VERTSPLIT)
6139 int hl;
[c2aa910]6140@@ -4813,6 +4914,10 @@
[ba61c16]6141
6142 off_from = (unsigned)(current_ScreenLine - ScreenLines);
6143 off_to = LineOffset[row] + coloff;
6144+#ifdef FEAT_MBYTE
6145+ max_off_from = off_from + screen_Columns;
6146+ max_off_to = LineOffset[row] + screen_Columns;
6147+#endif
6148
6149 #ifdef FEAT_RIGHTLEFT
6150 if (rlflag)
[c2aa910]6151@@ -4847,7 +4952,7 @@
[ba61c16]6152 {
6153 #ifdef FEAT_MBYTE
6154 if (has_mbyte && (col + 1 < endcol))
6155- char_cells = (*mb_off2cells)(off_from);
6156+ char_cells = (*mb_off2cells)(off_from, max_off_from);
6157 else
6158 char_cells = 1;
6159 #endif
[c2aa910]6160@@ -4924,7 +5029,7 @@
[ba61c16]6161 * ScreenLinesUC[] is sufficient. */
6162 if (char_cells == 1
6163 && col + 1 < endcol
6164- && (*mb_off2cells)(off_to) > 1)
6165+ && (*mb_off2cells)(off_to, max_off_to) > 1)
6166 {
6167 /* Writing a single-cell character over a double-cell
6168 * character: need to redraw the next cell. */
[c2aa910]6169@@ -4933,8 +5038,8 @@
[ba61c16]6170 }
6171 else if (char_cells == 2
6172 && col + 2 < endcol
6173- && (*mb_off2cells)(off_to) == 1
6174- && (*mb_off2cells)(off_to + 1) > 1)
6175+ && (*mb_off2cells)(off_to, max_off_to) == 1
6176+ && (*mb_off2cells)(off_to + 1, max_off_to) > 1)
6177 {
6178 /* Writing the second half of a double-cell character over
6179 * a double-cell character: need to redraw the second
[c2aa910]6180@@ -4953,10 +5058,10 @@
[ba61c16]6181 * char over the left halve of an existing one. */
6182 if (has_mbyte && col + char_cells == endcol
6183 && ((char_cells == 1
6184- && (*mb_off2cells)(off_to) > 1)
6185+ && (*mb_off2cells)(off_to, max_off_to) > 1)
6186 || (char_cells == 2
6187- && (*mb_off2cells)(off_to) == 1
6188- && (*mb_off2cells)(off_to + 1) > 1)))
6189+ && (*mb_off2cells)(off_to, max_off_to) == 1
6190+ && (*mb_off2cells)(off_to + 1, max_off_to) > 1)))
6191 clear_next = TRUE;
6192 #endif
6193
[c2aa910]6194@@ -5096,10 +5201,11 @@
[ba61c16]6195 /* find previous character by counting from first
6196 * column and get its width. */
6197 unsigned off = LineOffset[row];
6198+ unsigned max_off = LineOffset[row] + screen_Columns;
6199
6200 while (off < off_to)
6201 {
6202- prev_cells = (*mb_off2cells)(off);
6203+ prev_cells = (*mb_off2cells)(off, max_off);
6204 off += prev_cells;
6205 }
6206 }
[c2aa910]6207@@ -5285,7 +5391,7 @@
[ba61c16]6208 static int skip_status_match_char __ARGS((expand_T *xp, char_u *s));
6209
6210 /*
6211- * Get the lenght of an item as it will be shown in the status line.
6212+ * Get the length of an item as it will be shown in the status line.
6213 */
6214 static int
6215 status_match_len(xp, s)
[c2aa910]6216@@ -5351,7 +5457,7 @@
[ba61c16]6217 int row;
6218 char_u *buf;
6219 int len;
6220- int clen; /* lenght in screen cells */
6221+ int clen; /* length in screen cells */
6222 int fillchar;
6223 int attr;
6224 int i;
[c2aa910]6225@@ -6103,6 +6209,7 @@
[ba61c16]6226 char_u *ptr = text;
6227 int c;
6228 #ifdef FEAT_MBYTE
6229+ unsigned max_off;
6230 int mbyte_blen = 1;
6231 int mbyte_cells = 1;
6232 int u8c = 0;
[c2aa910]6233@@ -6119,8 +6226,12 @@
[ba61c16]6234 return;
6235
6236 off = LineOffset[row] + col;
6237- while (*ptr != NUL && col < screen_Columns
6238- && (len < 0 || (int)(ptr - text) < len))
6239+#ifdef FEAT_MBYTE
6240+ max_off = LineOffset[row] + screen_Columns;
6241+#endif
6242+ while (col < screen_Columns
6243+ && (len < 0 || (int)(ptr - text) < len)
6244+ && *ptr != NUL)
6245 {
6246 c = *ptr;
6247 #ifdef FEAT_MBYTE
[c2aa910]6248@@ -6143,6 +6254,7 @@
6249 else
6250 u8c = utfc_ptr2char(ptr, u8cc);
6251 mbyte_cells = utf_char2cells(u8c);
6252+# ifdef UNICODE16
6253 /* Non-BMP character: display as ? or fullwidth ?. */
6254 if (u8c >= 0x10000)
6255 {
6256@@ -6150,6 +6262,7 @@
6257 if (attr == 0)
6258 attr = hl_attr(HLF_8);
6259 }
6260+# endif
6261 # ifdef FEAT_ARABIC
6262 if (p_arshape && !p_tbidi && ARABIC_CHAR(u8c))
6263 {
6264@@ -6241,19 +6354,19 @@
[ba61c16]6265 else if (has_mbyte
6266 && (len < 0 ? ptr[mbyte_blen] == NUL
6267 : ptr + mbyte_blen >= text + len)
6268- && ((mbyte_cells == 1 && (*mb_off2cells)(off) > 1)
6269+ && ((mbyte_cells == 1 && (*mb_off2cells)(off, max_off) > 1)
6270 || (mbyte_cells == 2
6271- && (*mb_off2cells)(off) == 1
6272- && (*mb_off2cells)(off + 1) > 1)))
6273+ && (*mb_off2cells)(off, max_off) == 1
6274+ && (*mb_off2cells)(off + 1, max_off) > 1)))
6275 clear_next_cell = TRUE;
6276
6277 /* Make sure we never leave a second byte of a double-byte behind,
6278 * it confuses mb_off2cells(). */
6279 if (enc_dbcs
6280- && ((mbyte_cells == 1 && (*mb_off2cells)(off) > 1)
6281+ && ((mbyte_cells == 1 && (*mb_off2cells)(off, max_off) > 1)
6282 || (mbyte_cells == 2
6283- && (*mb_off2cells)(off) == 1
6284- && (*mb_off2cells)(off + 1) > 1)))
6285+ && (*mb_off2cells)(off, max_off) == 1
6286+ && (*mb_off2cells)(off + 1, max_off) > 1)))
6287 ScreenLines[off + mbyte_blen] = 0;
6288 #endif
6289 ScreenLines[off] = c;
[c2aa910]6290@@ -6318,7 +6431,7 @@
[ba61c16]6291
6292 #ifdef FEAT_SEARCH_EXTRA
6293 /*
6294- * Prepare for 'searchhl' highlighting.
6295+ * Prepare for 'hlsearch' highlighting.
6296 */
6297 static void
6298 start_search_hl()
[c2aa910]6299@@ -6331,7 +6444,7 @@
[ba61c16]6300 }
6301
6302 /*
6303- * Clean up for 'searchhl' highlighting.
6304+ * Clean up for 'hlsearch' highlighting.
6305 */
6306 static void
6307 end_search_hl()
[c2aa910]6308@@ -6351,18 +6464,28 @@
[ba61c16]6309 win_T *wp;
6310 linenr_T lnum;
6311 {
6312- match_T *shl; /* points to search_hl or match_hl */
6313+ matchitem_T *cur; /* points to the match list */
6314+ match_T *shl; /* points to search_hl or a match */
6315+ int shl_flag; /* flag to indicate whether search_hl
6316+ has been processed or not */
6317 int n;
6318- int i;
6319
6320 /*
6321 * When using a multi-line pattern, start searching at the top
6322 * of the window or just after a closed fold.
6323- * Do this both for search_hl and match_hl[3].
6324+ * Do this both for search_hl and the match list.
6325 */
6326- for (i = 3; i >= 0; --i)
6327+ cur = wp->w_match_head;
6328+ shl_flag = FALSE;
6329+ while (cur != NULL || shl_flag == FALSE)
6330 {
6331- shl = (i == 3) ? &search_hl : &match_hl[i];
6332+ if (shl_flag == FALSE)
6333+ {
6334+ shl = &search_hl;
6335+ shl_flag = TRUE;
6336+ }
6337+ else
6338+ shl = &cur->hl;
6339 if (shl->rm.regprog != NULL
6340 && shl->lnum == 0
6341 && re_multiline(shl->rm.regprog))
[c2aa910]6342@@ -6397,11 +6520,13 @@
[ba61c16]6343 }
6344 }
6345 }
6346+ if (shl != &search_hl && cur != NULL)
6347+ cur = cur->next;
6348 }
6349 }
6350
6351 /*
6352- * Search for a next 'searchl' or ":match" match.
6353+ * Search for a next 'hlsearch' or match.
6354 * Uses shl->buf.
6355 * Sets shl->lnum and shl->rm contents.
6356 * Note: Assumes a previous match is always before "lnum", unless
[c2aa910]6357@@ -6411,7 +6536,7 @@
[ba61c16]6358 static void
6359 next_search_hl(win, shl, lnum, mincol)
6360 win_T *win;
6361- match_T *shl; /* points to search_hl or match_hl */
6362+ match_T *shl; /* points to search_hl or a match */
6363 linenr_T lnum;
6364 colnr_T mincol; /* minimal column for a match */
6365 {
[c2aa910]6366@@ -6479,7 +6604,7 @@
[ba61c16]6367 /* Error while handling regexp: stop using this regexp. */
6368 if (shl == &search_hl)
6369 {
6370- /* don't free the regprog in match_hl[], it's a copy */
6371+ /* don't free regprog in the match list, it's a copy */
6372 vim_free(shl->rm.regprog);
6373 no_hlsearch = TRUE;
6374 }
[c2aa910]6375@@ -6827,6 +6952,9 @@
[ba61c16]6376 {
6377 int r, c;
6378 int off;
6379+#ifdef FEAT_MBYTE
6380+ int max_off;
6381+#endif
6382
6383 /* Can't use ScreenLines unless initialized */
6384 if (ScreenLines == NULL)
[c2aa910]6385@@ -6837,10 +6965,13 @@
[ba61c16]6386 for (r = row; r < row + height; ++r)
6387 {
6388 off = LineOffset[r];
6389+#ifdef FEAT_MBYTE
6390+ max_off = off + screen_Columns;
6391+#endif
6392 for (c = col; c < col + width; ++c)
6393 {
6394 #ifdef FEAT_MBYTE
6395- if (enc_dbcs != 0 && dbcs_off2cells(off + c) > 1)
6396+ if (enc_dbcs != 0 && dbcs_off2cells(off + c, max_off) > 1)
6397 {
6398 screen_char_2(off + c, r, c);
6399 ++c;
[c2aa910]6400@@ -6850,7 +6981,7 @@
[ba61c16]6401 {
6402 screen_char(off + c, r, c);
6403 #ifdef FEAT_MBYTE
6404- if (utf_off2cells(off + c) > 1)
6405+ if (utf_off2cells(off + c, max_off) > 1)
6406 ++c;
6407 #endif
6408 }
6409diff -Naur vim71.orig/src/search.c vim71/src/search.c
6410--- vim71.orig/src/search.c 2007-05-07 12:42:02.000000000 -0700
[c2aa910]6411+++ vim71/src/search.c 2007-10-16 14:14:09.000000000 -0700
[ba61c16]6412@@ -101,7 +101,6 @@
6413 static char_u *mr_pattern = NULL; /* pattern used by search_regcomp() */
6414 #ifdef FEAT_RIGHTLEFT
6415 static int mr_pattern_alloced = FALSE; /* mr_pattern was allocated */
6416-static char_u *reverse_text __ARGS((char_u *s));
6417 #endif
6418
6419 #ifdef FEAT_FIND_ID
6420@@ -228,12 +227,12 @@
6421 return mr_pattern;
6422 }
6423
6424-#ifdef FEAT_RIGHTLEFT
6425+#if defined(FEAT_RIGHTLEFT) || defined(PROTO)
6426 /*
6427 * Reverse text into allocated memory.
6428 * Returns the allocated string, NULL when out of memory.
6429 */
6430- static char_u *
6431+ char_u *
6432 reverse_text(s)
6433 char_u *s;
6434 {
6435@@ -573,8 +572,12 @@
6436 /*
6437 * Start searching in current line, unless searching backwards and
6438 * we're in column 0.
6439+ * If we are searching backwards, in column 0, and not including the
6440+ * current position, gain some efficiency by skipping back a line.
6441+ * Otherwise begin the search in the current line.
6442 */
6443- if (dir == BACKWARD && start_pos.col == 0)
6444+ if (dir == BACKWARD && start_pos.col == 0
6445+ && (options & SEARCH_START) == 0)
6446 {
6447 lnum = pos->lnum - 1;
6448 at_first_line = FALSE;
6449@@ -1894,7 +1897,7 @@
6450 }
6451
6452 #ifdef FEAT_RIGHTLEFT
6453- /* This is just guessing: when 'rightleft' is set, search for a maching
6454+ /* This is just guessing: when 'rightleft' is set, search for a matching
6455 * paren/brace in the other direction. */
6456 if (curwin->w_p_rl && vim_strchr((char_u *)"()[]{}<>", initc) != NULL)
6457 backwards = !backwards;
6458@@ -2124,6 +2127,9 @@
6459 else if (!backwards)
6460 inquote = TRUE;
6461 }
6462+
6463+ /* ml_get() only keeps one line, need to get linep again */
6464+ linep = ml_get(pos.lnum);
6465 }
6466 }
6467 }
6468@@ -2795,7 +2801,7 @@
6469 i = inc_cursor();
6470 if (i == -1 || (i >= 1 && last_line)) /* started at last char in file */
6471 return FAIL;
6472- if (i == 1 && eol && count == 0) /* started at last char in line */
6473+ if (i >= 1 && eol && count == 0) /* started at last char in line */
6474 return OK;
6475
6476 /*
6477@@ -3600,13 +3606,16 @@
6478 {
6479 oap->start = start_pos;
6480 oap->motion_type = MCHAR;
6481+ oap->inclusive = FALSE;
6482 if (sol)
6483- {
6484 incl(&curwin->w_cursor);
6485- oap->inclusive = FALSE;
6486- }
6487- else
6488+ else if (lt(start_pos, curwin->w_cursor))
6489+ /* Include the character under the cursor. */
6490 oap->inclusive = TRUE;
6491+ else
6492+ /* End is before the start (no text in between <>, [], etc.): don't
6493+ * operate on any text. */
6494+ curwin->w_cursor = start_pos;
6495 }
6496
6497 return OK;
6498@@ -3734,7 +3743,7 @@
6499
6500 if (in_html_tag(FALSE))
6501 {
6502- /* cursor on start tag, move to just after it */
6503+ /* cursor on start tag, move to its '>' */
6504 while (*ml_get_cursor() != '>')
6505 if (inc_cursor() < 0)
6506 break;
6507@@ -3838,7 +3847,7 @@
6508 /* Exclude the start tag. */
6509 curwin->w_cursor = start_pos;
6510 while (inc_cursor() >= 0)
6511- if (*ml_get_cursor() == '>' && lt(curwin->w_cursor, end_pos))
6512+ if (*ml_get_cursor() == '>')
6513 {
6514 inc_cursor();
6515 start_pos = curwin->w_cursor;
6516@@ -3860,7 +3869,11 @@
6517 #ifdef FEAT_VISUAL
6518 if (VIsual_active)
6519 {
6520- if (*p_sel == 'e')
6521+ /* If the end is before the start there is no text between tags, select
6522+ * the char under the cursor. */
6523+ if (lt(end_pos, start_pos))
6524+ curwin->w_cursor = start_pos;
6525+ else if (*p_sel == 'e')
6526 ++curwin->w_cursor.col;
6527 VIsual = start_pos;
6528 VIsual_mode = 'v';
6529@@ -3872,7 +3885,15 @@
6530 {
6531 oap->start = start_pos;
6532 oap->motion_type = MCHAR;
6533- oap->inclusive = TRUE;
6534+ if (lt(end_pos, start_pos))
6535+ {
6536+ /* End is before the start: there is no text between tags; operate
6537+ * on an empty area. */
6538+ curwin->w_cursor = start_pos;
6539+ oap->inclusive = FALSE;
6540+ }
6541+ else
6542+ oap->inclusive = TRUE;
6543 }
6544 retval = OK;
6545
6546diff -Naur vim71.orig/src/spell.c vim71/src/spell.c
6547--- vim71.orig/src/spell.c 2007-05-07 12:48:38.000000000 -0700
[c2aa910]6548+++ vim71/src/spell.c 2007-10-16 14:14:09.000000000 -0700
[ba61c16]6549@@ -7829,7 +7829,7 @@
6550 # if (_MSC_VER <= 1200)
6551 /* This line is required for VC6 without the service pack. Also see the
6552 * matching #pragma below. */
6553-/* # pragma optimize("", off) */
6554+ # pragma optimize("", off)
6555 # endif
6556 #endif
6557
6558@@ -7859,7 +7859,7 @@
6559
6560 #ifdef _MSC_VER
6561 # if (_MSC_VER <= 1200)
6562-/* # pragma optimize("", on) */
6563+ # pragma optimize("", on)
6564 # endif
6565 #endif
6566
6567@@ -12182,7 +12182,9 @@
6568 {
6569 n = mb_cptr2len(p);
6570 c = mb_ptr2char(p);
6571- if (!soundfold && !spell_iswordp(p + n, curbuf))
6572+ if (p[n] == NUL)
6573+ c2 = NUL;
6574+ else if (!soundfold && !spell_iswordp(p + n, curbuf))
6575 c2 = c; /* don't swap non-word char */
6576 else
6577 c2 = mb_ptr2char(p + n);
6578@@ -12190,12 +12192,21 @@
6579 else
6580 #endif
6581 {
6582- if (!soundfold && !spell_iswordp(p + 1, curbuf))
6583+ if (p[1] == NUL)
6584+ c2 = NUL;
6585+ else if (!soundfold && !spell_iswordp(p + 1, curbuf))
6586 c2 = c; /* don't swap non-word char */
6587 else
6588 c2 = p[1];
6589 }
6590
6591+ /* When the second character is NUL we can't swap. */
6592+ if (c2 == NUL)
6593+ {
6594+ sp->ts_state = STATE_REP_INI;
6595+ break;
6596+ }
6597+
6598 /* When characters are identical, swap won't do anything.
6599 * Also get here if the second char is not a word character. */
6600 if (c == c2)
6601diff -Naur vim71.orig/src/structs.h vim71/src/structs.h
6602--- vim71.orig/src/structs.h 2007-05-07 12:50:49.000000000 -0700
[c2aa910]6603+++ vim71/src/structs.h 2007-10-16 14:14:38.000000000 -0700
6604@@ -278,6 +278,9 @@
6605 linenr_T ue_lcount; /* linecount when u_save called */
6606 char_u **ue_array; /* array of lines in undo block */
6607 long ue_size; /* number of lines in ue_array */
6608+#ifdef U_DEBUG
6609+ int ue_magic; /* magic number to check allocation */
6610+#endif
6611 };
6612
6613 struct u_header
6614@@ -300,6 +303,9 @@
6615 visualinfo_T uh_visual; /* Visual areas before undo/after redo */
6616 #endif
6617 time_t uh_time; /* timestamp when the change was made */
6618+#ifdef U_DEBUG
6619+ int uh_magic; /* magic number to check allocation */
6620+#endif
6621 };
6622
6623 /* values for uh_flags */
6624@@ -1453,6 +1459,7 @@
[ba61c16]6625 #ifdef FEAT_MBYTE
6626 char_u *b_start_fenc; /* 'fileencoding' when edit started or NULL */
6627 int b_bad_char; /* "++bad=" argument when edit started or 0 */
6628+ int b_start_bomb; /* 'bomb' when it was read */
6629 #endif
6630
6631 #ifdef FEAT_EVAL
[c2aa910]6632@@ -1694,6 +1701,41 @@
[ba61c16]6633 #define FR_COL 2 /* frame with a column of windows */
6634
6635 /*
6636+ * Struct used for highlighting 'hlsearch' matches, matches defined by
6637+ * ":match" and matches defined by match functions.
6638+ * For 'hlsearch' there is one pattern for all windows. For ":match" and the
6639+ * match functions there is a different pattern for each window.
6640+ */
6641+typedef struct
6642+{
6643+ regmmatch_T rm; /* points to the regexp program; contains last found
6644+ match (may continue in next line) */
6645+ buf_T *buf; /* the buffer to search for a match */
6646+ linenr_T lnum; /* the line to search for a match */
6647+ int attr; /* attributes to be used for a match */
6648+ int attr_cur; /* attributes currently active in win_line() */
6649+ linenr_T first_lnum; /* first lnum to search for multi-line pat */
6650+ colnr_T startcol; /* in win_line() points to char where HL starts */
6651+ colnr_T endcol; /* in win_line() points to char where HL ends */
6652+} match_T;
6653+
6654+/*
6655+ * matchitem_T provides a linked list for storing match items for ":match" and
6656+ * the match functions.
6657+ */
6658+typedef struct matchitem matchitem_T;
6659+struct matchitem
6660+{
6661+ matchitem_T *next;
6662+ int id; /* match ID */
6663+ int priority; /* match priority */
6664+ char_u *pattern; /* pattern to highlight */
6665+ int hlg_id; /* highlight group ID */
6666+ regmmatch_T match; /* regexp program for pattern */
6667+ match_T hl; /* struct for doing the actual highlighting */
6668+};
6669+
6670+/*
6671 * Structure which contains all information that belongs to a window
6672 *
6673 * All row numbers are relative to the start of the window, except w_winrow.
[c2aa910]6674@@ -1934,9 +1976,8 @@
[ba61c16]6675 #endif
6676
6677 #ifdef FEAT_SEARCH_EXTRA
6678- regmmatch_T w_match[3]; /* regexp programs for ":match" */
6679- char_u *(w_match_pat[3]); /* patterns for ":match" */
6680- int w_match_id[3]; /* highlight IDs for ":match" */
6681+ matchitem_T *w_match_head; /* head of match list */
6682+ int w_next_match_id; /* next match ID */
6683 #endif
6684
6685 /*
6686diff -Naur vim71.orig/src/syntax.c vim71/src/syntax.c
6687--- vim71.orig/src/syntax.c 2007-05-07 12:42:55.000000000 -0700
[c2aa910]6688+++ vim71/src/syntax.c 2007-10-16 14:14:41.000000000 -0700
[ba61c16]6689@@ -66,8 +66,10 @@
6690 #define HL_TABLE() ((struct hl_group *)((highlight_ga.ga_data)))
6691
6692 #ifdef FEAT_CMDL_COMPL
6693-static int include_default = FALSE; /* include "default" for expansion */
6694-static int include_link = FALSE; /* include "link" for expansion */
6695+/* Flags to indicate an additional string for highlight name completion. */
6696+static int include_none = 0; /* when 1 include "None" */
6697+static int include_default = 0; /* when 1 include "default" */
6698+static int include_link = 0; /* when 2 include "link" and "clear" */
6699 #endif
6700
6701 /*
6702@@ -277,7 +279,8 @@
6703 */
6704 typedef struct state_item
6705 {
6706- int si_idx; /* index of syntax pattern */
6707+ int si_idx; /* index of syntax pattern or
6708+ KEYWORD_IDX */
6709 int si_id; /* highlight group ID for keywords */
6710 int si_trans_id; /* idem, transparancy removed */
6711 int si_m_lnum; /* lnum of the match */
6712@@ -835,9 +838,18 @@
6713 current_lnum = end_lnum;
6714 break;
6715 }
6716- spp = &(SYN_ITEMS(syn_buf)[cur_si->si_idx]);
6717- found_flags = spp->sp_flags;
6718- found_match_idx = spp->sp_sync_idx;
6719+ if (cur_si->si_idx < 0)
6720+ {
6721+ /* Cannot happen? */
6722+ found_flags = 0;
6723+ found_match_idx = KEYWORD_IDX;
6724+ }
6725+ else
6726+ {
6727+ spp = &(SYN_ITEMS(syn_buf)[cur_si->si_idx]);
6728+ found_flags = spp->sp_flags;
6729+ found_match_idx = spp->sp_sync_idx;
6730+ }
6731 found_current_lnum = current_lnum;
6732 found_current_col = current_col;
6733 found_m_endpos = cur_si->si_m_endpos;
6734@@ -1725,6 +1737,13 @@
6735 {
6736 int attr = 0;
6737
6738+ if (can_spell != NULL)
6739+ /* Default: Only do spelling when there is no @Spell cluster or when
6740+ * ":syn spell toplevel" was used. */
6741+ *can_spell = syn_buf->b_syn_spell == SYNSPL_DEFAULT
6742+ ? (syn_buf->b_spell_cluster_id == 0)
6743+ : (syn_buf->b_syn_spell == SYNSPL_TOP);
6744+
6745 /* check for out of memory situation */
6746 if (syn_buf->b_sst_array == NULL)
6747 return 0;
6748@@ -2524,6 +2543,10 @@
6749 stateitem_T *sip = &CUR_STATE(idx);
6750 synpat_T *spp;
6751
6752+ /* This should not happen... */
6753+ if (sip->si_idx < 0)
6754+ return;
6755+
6756 spp = &(SYN_ITEMS(syn_buf)[sip->si_idx]);
6757 if (sip->si_flags & HL_MATCH)
6758 sip->si_id = spp->sp_syn_match_id;
6759@@ -2639,6 +2662,10 @@
6760 lpos_T end_endpos;
6761 int end_idx;
6762
6763+ /* return quickly for a keyword */
6764+ if (sip->si_idx < 0)
6765+ return;
6766+
6767 /* Don't update when it's already done. Can be a match of an end pattern
6768 * that started in a previous line. Watch out: can also be a "keepend"
6769 * from a containing item. */
6770@@ -2751,6 +2778,10 @@
6771 char_u *line;
6772 int had_match = FALSE;
6773
6774+ /* just in case we are invoked for a keyword */
6775+ if (idx < 0)
6776+ return;
6777+
6778 /*
6779 * Check for being called with a START pattern.
6780 * Can happen with a match that continues to the next line, because it
[c2aa910]6781@@ -3323,6 +3354,7 @@
6782 {
6783 vim_free(SYN_ITEMS(buf)[i].sp_cont_list);
6784 vim_free(SYN_ITEMS(buf)[i].sp_next_list);
6785+ vim_free(SYN_ITEMS(buf)[i].sp_syn.cont_in_list);
6786 }
6787 }
6788
6789@@ -4460,8 +4492,8 @@
[ba61c16]6790 current_syn_inc_tag = ++running_syn_inc_tag;
6791 prev_toplvl_grp = curbuf->b_syn_topgrp;
6792 curbuf->b_syn_topgrp = sgl_id;
6793- if (source ? do_source(eap->arg, FALSE, FALSE) == FAIL
6794- : source_runtime(eap->arg, DOSO_NONE) == FAIL)
6795+ if (source ? do_source(eap->arg, FALSE, DOSO_NONE) == FAIL
6796+ : source_runtime(eap->arg, TRUE) == FAIL)
6797 EMSG2(_(e_notopen), eap->arg);
6798 curbuf->b_syn_topgrp = prev_toplvl_grp;
6799 current_syn_inc_tag = prev_syn_inc_tag;
[c2aa910]6800@@ -5956,8 +5988,8 @@
[ba61c16]6801 {
6802 return (buf->b_syn_patterns.ga_len != 0
6803 || buf->b_syn_clusters.ga_len != 0
6804- || curbuf->b_keywtab.ht_used > 0
6805- || curbuf->b_keywtab_ic.ht_used > 0);
6806+ || buf->b_keywtab.ht_used > 0
6807+ || buf->b_keywtab_ic.ht_used > 0);
6808 }
6809
6810 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
[c2aa910]6811@@ -5968,6 +6000,29 @@
[ba61c16]6812 EXP_CASE /* expand ":syn case" arguments */
6813 } expand_what;
6814
6815+/*
6816+ * Reset include_link, include_default, include_none to 0.
6817+ * Called when we are done expanding.
6818+ */
6819+ void
6820+reset_expand_highlight()
6821+{
6822+ include_link = include_default = include_none = 0;
6823+}
6824+
6825+/*
6826+ * Handle command line completion for :match and :echohl command: Add "None"
6827+ * as highlight group.
6828+ */
6829+ void
6830+set_context_in_echohl_cmd(xp, arg)
6831+ expand_T *xp;
6832+ char_u *arg;
6833+{
6834+ xp->xp_context = EXPAND_HIGHLIGHT;
6835+ xp->xp_pattern = arg;
6836+ include_none = 1;
6837+}
6838
6839 /*
6840 * Handle command line completion for :syntax command.
[c2aa910]6841@@ -5983,8 +6038,8 @@
[ba61c16]6842 xp->xp_context = EXPAND_SYNTAX;
6843 expand_what = EXP_SUBCMD;
6844 xp->xp_pattern = arg;
6845- include_link = FALSE;
6846- include_default = FALSE;
6847+ include_link = 0;
6848+ include_default = 0;
6849
6850 /* (part of) subcommand already typed */
6851 if (*arg != NUL)
[c2aa910]6852@@ -8479,7 +8534,7 @@
[ba61c16]6853 syn_id2name(id)
6854 int id;
6855 {
6856- if (id <= 0 || id >= highlight_ga.ga_len)
6857+ if (id <= 0 || id > highlight_ga.ga_len)
6858 return (char_u *)"";
6859 return HL_TABLE()[id - 1].sg_name;
6860 }
[c2aa910]6861@@ -8949,7 +9004,7 @@
[ba61c16]6862 return OK;
6863 }
6864
6865-#ifdef FEAT_CMDL_COMPL
6866+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
6867
6868 static void highlight_list __ARGS((void));
6869 static void highlight_list_two __ARGS((int cnt, int attr));
[c2aa910]6870@@ -8967,8 +9022,8 @@
[ba61c16]6871 /* Default: expand group names */
6872 xp->xp_context = EXPAND_HIGHLIGHT;
6873 xp->xp_pattern = arg;
6874- include_link = TRUE;
6875- include_default = TRUE;
6876+ include_link = 2;
6877+ include_default = 1;
6878
6879 /* (part of) subcommand already typed */
6880 if (*arg != NUL)
[c2aa910]6881@@ -8976,7 +9031,7 @@
[ba61c16]6882 p = skiptowhite(arg);
6883 if (*p != NUL) /* past "default" or group name */
6884 {
6885- include_default = FALSE;
6886+ include_default = 0;
6887 if (STRNCMP("default", arg, p - arg) == 0)
6888 {
6889 arg = skipwhite(p);
[c2aa910]6890@@ -8985,7 +9040,7 @@
[ba61c16]6891 }
6892 if (*p != NUL) /* past group name */
6893 {
6894- include_link = FALSE;
6895+ include_link = 0;
6896 if (arg[1] == 'i' && arg[0] == 'N')
6897 highlight_list();
6898 if (STRNCMP("link", arg, p - arg) == 0
[c2aa910]6899@@ -9045,31 +9100,25 @@
[ba61c16]6900 expand_T *xp;
6901 int idx;
6902 {
6903- if (idx == highlight_ga.ga_len
6904 #ifdef FEAT_CMDL_COMPL
6905- && include_link
6906-#endif
6907- )
6908+ if (idx == highlight_ga.ga_len && include_none != 0)
6909+ return (char_u *)"none";
6910+ if (idx == highlight_ga.ga_len + include_none && include_default != 0)
6911+ return (char_u *)"default";
6912+ if (idx == highlight_ga.ga_len + include_none + include_default
6913+ && include_link != 0)
6914 return (char_u *)"link";
6915- if (idx == highlight_ga.ga_len + 1
6916-#ifdef FEAT_CMDL_COMPL
6917- && include_link
6918-#endif
6919- )
6920+ if (idx == highlight_ga.ga_len + include_none + include_default + 1
6921+ && include_link != 0)
6922 return (char_u *)"clear";
6923- if (idx == highlight_ga.ga_len + 2
6924-#ifdef FEAT_CMDL_COMPL
6925- && include_default
6926 #endif
6927- )
6928- return (char_u *)"default";
6929 if (idx < 0 || idx >= highlight_ga.ga_len)
6930 return NULL;
6931 return HL_TABLE()[idx].sg_name;
6932 }
6933 #endif
6934
6935-#ifdef FEAT_GUI
6936+#if defined(FEAT_GUI) || defined(PROTO)
6937 /*
6938 * Free all the highlight group fonts.
6939 * Used when quitting for systems which need it.
[c2aa910]6940diff -Naur vim71.orig/src/term.c vim71/src/term.c
6941--- vim71.orig/src/term.c 2007-05-07 12:39:11.000000000 -0700
6942+++ vim71/src/term.c 2007-10-16 14:14:28.000000000 -0700
6943@@ -4809,6 +4809,8 @@
6944 if (num_bytes == -1)
6945 return -1;
6946 current_tab = (int)bytes[0];
6947+ if (current_tab == 255) /* -1 in a byte gives 255 */
6948+ current_tab = -1;
6949 slen += num_bytes;
6950 }
6951 else if (key_name[0] == (int)KS_TABMENU)
[ba61c16]6952diff -Naur vim71.orig/src/termlib.c vim71/src/termlib.c
6953--- vim71.orig/src/termlib.c 2007-05-07 12:39:49.000000000 -0700
[c2aa910]6954+++ vim71/src/termlib.c 2007-10-16 14:14:09.000000000 -0700
[ba61c16]6955@@ -191,7 +191,7 @@
6956 lbuf[0] == '\t' &&
6957 lbuf[1] == ':')
6958 {
6959- strcpy(lbuf, lbuf+2);
6960+ mch_memmove(lbuf, lbuf + 2, strlen(lbuf + 2) + 1);
6961 llen -= 2;
6962 }
6963 if (lbuf[llen-2] == '\\') /* and continuations */
6964diff -Naur vim71.orig/src/testdir/Makefile vim71/src/testdir/Makefile
6965--- vim71.orig/src/testdir/Makefile 2006-04-30 04:08:01.000000000 -0700
[c2aa910]6966+++ vim71/src/testdir/Makefile 2007-10-16 14:14:28.000000000 -0700
[ba61c16]6967@@ -1,9 +1,13 @@
6968 #
6969-# Makefile to run al tests for Vim
6970+# Makefile to run all tests for Vim
6971 #
6972
6973 VIMPROG = ../vim
6974
6975+# Uncomment this line for using valgrind.
6976+# The output goes into a file "valgrind.$PID" (sorry, no test number).
[c2aa910]6977+# VALGRIND = valgrind --tool=memcheck --leak-check=yes --num-callers=15 --logfile=valgrind
[ba61c16]6978+
6979 SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \
6980 test7.out test8.out test9.out test10.out test11.out \
6981 test12.out test13.out test14.out test15.out test17.out \
6982@@ -15,7 +19,8 @@
6983 test43.out test44.out test45.out test46.out test47.out \
6984 test48.out test49.out test51.out test52.out test53.out \
6985 test54.out test55.out test56.out test57.out test58.out \
6986- test59.out test60.out test61.out test62.out
6987+ test59.out test60.out test61.out test62.out test63.out \
6988+ test64.out
6989
6990 SCRIPTS_GUI = test16.out
6991
[c2aa910]6992@@ -34,11 +39,11 @@
6993 $(SCRIPTS) $(SCRIPTS_GUI): $(VIMPROG)
6994
6995 clean:
6996- -rm -rf *.out *.failed *.rej *.orig test.log tiny.vim small.vim mbyte.vim test.ok X* viminfo
6997+ -rm -rf *.out *.failed *.rej *.orig test.log tiny.vim small.vim mbyte.vim test.ok X* valgrind.pid* viminfo
[ba61c16]6998
6999 test1.out: test1.in
7000 -rm -f $*.failed tiny.vim small.vim mbyte.vim test.ok X* viminfo
7001- $(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
7002+ $(VALGRIND) $(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
7003 @/bin/sh -c "if diff test.out $*.ok; \
7004 then mv -f test.out $*.out; \
7005 else echo; \
7006@@ -51,7 +56,7 @@
7007 cp $*.ok test.ok
7008 # Sleep a moment to avoid that the xterm title is messed up
7009 @-sleep .2
7010- -$(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
7011+ -$(VALGRIND) $(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
7012 @/bin/sh -c "if test -f test.out; then\
7013 if diff test.out $*.ok; \
7014 then mv -f test.out $*.out; \
[c2aa910]7015@@ -61,5 +66,9 @@
7016 fi"
7017 -rm -rf X* test.ok viminfo
7018
7019+test49.out: test49.vim
7020+
7021+test60.out: test60.vim
7022+
7023 nolog:
7024 -echo Test results: >test.log
7025diff -Naur vim71.orig/src/testdir/test14.in vim71/src/testdir/test14.in
7026--- vim71.orig/src/testdir/test14.in 2004-06-07 07:32:05.000000000 -0700
7027+++ vim71/src/testdir/test14.in 2007-10-16 14:14:28.000000000 -0700
7028@@ -18,6 +18,7 @@
7029 : let tt = "o\<C-V>65\<C-V>x42\<C-V>o103 \<C-V>33a\<C-V>xfg\<C-V>o78\<Esc>"
7030 :endif
7031 :exe "normal " . tt
7032+:unlet tt
7033 :.w >>test.out
7034 :set vb
7035 /^Piece
7036diff -Naur vim71.orig/src/testdir/test26.in vim71/src/testdir/test26.in
7037--- vim71.orig/src/testdir/test26.in 2004-06-07 07:32:05.000000000 -0700
7038+++ vim71/src/testdir/test26.in 2007-10-16 14:14:28.000000000 -0700
7039@@ -37,6 +37,7 @@
7040 : endif
7041 : endif
7042 :endwhile
7043+:unlet i j
7044 :'t,$w! test.out
7045 :qa!
7046 ENDTEST
7047diff -Naur vim71.orig/src/testdir/test34.in vim71/src/testdir/test34.in
7048--- vim71.orig/src/testdir/test34.in 2006-04-30 06:33:24.000000000 -0700
7049+++ vim71/src/testdir/test34.in 2007-10-16 14:14:28.000000000 -0700
7050@@ -52,7 +52,15 @@
7051 ---*---
7052 (one
7053 (two
7054-[(one again:$-5,$wq! test.out
7055+[(one again:$-5,$w! test.out
7056+:delfunc Table
7057+:delfunc Compute
7058+:delfunc Expr1
7059+:delfunc Expr2
7060+:delfunc ListItem
7061+:delfunc ListReset
7062+:unlet retval counter
7063+:q!
7064 ENDTEST
7065
7066 here
7067diff -Naur vim71.orig/src/testdir/test45.in vim71/src/testdir/test45.in
7068--- vim71.orig/src/testdir/test45.in 2004-06-07 07:32:05.000000000 -0700
7069+++ vim71/src/testdir/test45.in 2007-10-16 14:14:28.000000000 -0700
7070@@ -55,6 +55,7 @@
7071 /kk$
7072 :call append("$", foldlevel("."))
7073 :/^last/+1,$w! test.out
7074+:delfun Flvl
7075 :qa!
7076 ENDTEST
7077
7078diff -Naur vim71.orig/src/testdir/test47.in vim71/src/testdir/test47.in
7079--- vim71.orig/src/testdir/test47.in 2004-06-07 07:32:05.000000000 -0700
7080+++ vim71/src/testdir/test47.in 2007-10-16 14:14:28.000000000 -0700
7081@@ -34,6 +34,7 @@
7082 :call append("$", two)
7083 :call append("$", three)
7084 :$-2,$w! test.out
7085+:unlet one two three
7086 :qa!
7087 ENDTEST
7088
7089diff -Naur vim71.orig/src/testdir/test49.in vim71/src/testdir/test49.in
7090--- vim71.orig/src/testdir/test49.in 2006-04-28 02:29:54.000000000 -0700
7091+++ vim71/src/testdir/test49.in 2007-10-16 14:14:28.000000000 -0700
7092@@ -1,13 +1,29 @@
7093 This is a test of the script language.
7094
7095 If after adding a new test, the test output doesn't appear properly in
7096-test49.failed, try to add one ore more "G"s at the line before ENDTEST.
7097+test49.failed, try to add one ore more "G"s at the line ending in "test.out"
7098
7099 STARTTEST
7100 :so small.vim
7101 :se nocp nomore viminfo+=nviminfo
7102 :so test49.vim
7103-GGGGGGGGGG"rp:.-,$wq! test.out
7104+GGGGGGGGGGGGGG"rp:.-,$w! test.out
7105+:"
7106+:" make valgrind happy
7107+:redir => funclist
7108+:silent func
7109+:redir END
7110+:for line in split(funclist, "\n")
7111+: let name = matchstr(line, 'function \zs[A-Z]\w*\ze(')
7112+: if name != ''
7113+: exe "delfunc " . name
7114+: endif
7115+:endfor
7116+:for v in keys(g:)
7117+: silent! exe "unlet " . v
7118+:endfor
7119+:unlet v
7120+:qa!
7121 ENDTEST
7122
7123 Results of test49.vim:
7124diff -Naur vim71.orig/src/testdir/test55.in vim71/src/testdir/test55.in
7125--- vim71.orig/src/testdir/test55.in 2006-10-15 07:07:05.000000000 -0700
7126+++ vim71/src/testdir/test55.in 2007-10-16 14:14:28.000000000 -0700
7127@@ -345,6 +345,10 @@
7128 :endfun
7129 :call Test(1, 2, [3, 4], {5: 6}) " This may take a while
7130 :"
7131+:delfunc Test
7132+:unlet dict
7133+:call garbagecollect(1)
7134+:"
7135 :/^start:/,$wq! test.out
7136 ENDTEST
7137
7138diff -Naur vim71.orig/src/testdir/test56.in vim71/src/testdir/test56.in
7139--- vim71.orig/src/testdir/test56.in 2006-09-03 07:28:41.000000000 -0700
7140+++ vim71/src/testdir/test56.in 2007-10-16 14:14:28.000000000 -0700
7141@@ -17,5 +17,5 @@
7142 fun s:DoNothing()
7143 call append(line('$'), "nothing line")
7144 endfun
7145-nnoremap <buffer> _x :call <SID>DoNothing()<bar>call <SID>DoLast()<cr>
7146+nnoremap <buffer> _x :call <SID>DoNothing()<bar>call <SID>DoLast()<bar>delfunc <SID>DoNothing<bar>delfunc <SID>DoLast<cr>
7147 end:
7148diff -Naur vim71.orig/src/testdir/test58.in vim71/src/testdir/test58.in
7149--- vim71.orig/src/testdir/test58.in 2006-04-03 11:24:04.000000000 -0700
7150+++ vim71/src/testdir/test58.in 2007-10-16 14:14:28.000000000 -0700
7151@@ -86,6 +86,7 @@
7152 :$put =str
7153 `m]s:let [str, a] = spellbadword()
7154 :$put =str
7155+:unlet str a
7156 :"
7157 :" Postponed prefixes
7158 :call TestOne('2', '1')
7159@@ -100,6 +101,10 @@
7160 :" NOSLITSUGS
7161 :call TestOne('8', '8')
7162 :"
7163+:" clean up for valgrind
7164+:delfunc TestOne
7165+:set spl= enc=latin1
7166+:"
7167 gg:/^test output:/,$wq! test.out
7168 ENDTEST
7169
7170diff -Naur vim71.orig/src/testdir/test59.in vim71/src/testdir/test59.in
7171--- vim71.orig/src/testdir/test59.in 2006-04-03 11:29:24.000000000 -0700
7172+++ vim71/src/testdir/test59.in 2007-10-16 14:14:28.000000000 -0700
7173@@ -90,6 +90,7 @@
7174 :$put =str
7175 `m]s:let [str, a] = spellbadword()
7176 :$put =str
7177+:unlet str a
7178 :"
7179 :" Postponed prefixes
7180 :call TestOne('2', '1')
7181@@ -101,6 +102,10 @@
7182 :call TestOne('6', '6')
7183 :call TestOne('7', '7')
7184 :"
7185+:" clean up for valgrind
7186+:delfunc TestOne
7187+:set spl= enc=latin1
7188+:"
7189 gg:/^test output:/,$wq! test.out
7190 ENDTEST
7191
7192diff -Naur vim71.orig/src/testdir/test60.in vim71/src/testdir/test60.in
7193--- vim71.orig/src/testdir/test60.in 2006-05-05 11:41:18.000000000 -0700
7194+++ vim71/src/testdir/test60.in 2007-10-16 14:14:28.000000000 -0700
7195@@ -569,6 +569,9 @@
7196 redir END
7197 endfunction
7198 :call TestExists()
7199+:delfunc TestExists
7200+:delfunc RunTest
7201+:delfunc TestFuncArg
7202 :edit! test.out
7203 :set ff=unix
7204 :w
7205diff -Naur vim71.orig/src/testdir/test60.vim vim71/src/testdir/test60.vim
7206--- vim71.orig/src/testdir/test60.vim 2006-01-12 11:45:59.000000000 -0800
7207+++ vim71/src/testdir/test60.vim 2007-10-16 14:14:28.000000000 -0700
7208@@ -94,4 +94,5 @@
7209 else
7210 echo "FAILED"
7211 endif
7212+unlet str
7213
7214diff -Naur vim71.orig/src/testdir/test62.in vim71/src/testdir/test62.in
7215--- vim71.orig/src/testdir/test62.in 2006-04-30 04:29:15.000000000 -0700
7216+++ vim71/src/testdir/test62.in 2007-10-16 14:14:28.000000000 -0700
7217@@ -7,6 +7,7 @@
7218 :let nr = tabpagenr()
7219 :q
7220 :call append(line('$'), 'tab page ' . nr)
7221+:unlet nr
7222 :"
7223 :" Open three tab pages and use ":tabdo"
7224 :0tabnew
7225@@ -23,6 +24,7 @@
7226 :q!
7227 :call append(line('$'), line1)
7228 :call append(line('$'), line2)
7229+:unlet line1 line2
7230 :"
7231 :"
7232 :/^Results/,$w! test.out
[ba61c16]7233diff -Naur vim71.orig/src/testdir/test63.in vim71/src/testdir/test63.in
7234--- vim71.orig/src/testdir/test63.in 1969-12-31 16:00:00.000000000 -0800
[c2aa910]7235+++ vim71/src/testdir/test63.in 2007-10-16 14:14:28.000000000 -0700
[ba61c16]7236@@ -0,0 +1,157 @@
7237+Test for ":match", ":2match", ":3match", "clearmatches()", "getmatches()",
7238+"matchadd()", "matcharg()", "matchdelete()", and "setmatches()".
7239+
7240+STARTTEST
7241+:so small.vim
7242+:" --- Check that "matcharg()" returns the correct group and pattern if a match
7243+:" --- is defined.
7244+:let @r = "*** Test 1: "
7245+:highlight MyGroup1 ctermbg=red
7246+:highlight MyGroup2 ctermbg=green
7247+:highlight MyGroup3 ctermbg=blue
7248+:match MyGroup1 /TODO/
7249+:2match MyGroup2 /FIXME/
7250+:3match MyGroup3 /XXX/
7251+:if matcharg(1) == ['MyGroup1', 'TODO'] && matcharg(2) == ['MyGroup2', 'FIXME'] && matcharg(3) == ['MyGroup3', 'XXX']
7252+: let @r .= "OK\n"
7253+:else
7254+: let @r .= "FAILED\n"
7255+:endif
7256+:" --- Check that "matcharg()" returns an empty list if the argument is not 1,
7257+:" --- 2 or 3 (only 0 and 4 are tested).
7258+:let @r .= "*** Test 2: "
7259+:if matcharg(0) == [] && matcharg(4) == []
7260+: let @r .= "OK\n"
7261+:else
7262+: let @r .= "FAILED\n"
7263+:endif
7264+:" --- Check that "matcharg()" returns ['', ''] if a match is not defined.
7265+:let @r .= "*** Test 3: "
7266+:match
7267+:2match
7268+:3match
7269+:if matcharg(1) == ['', ''] && matcharg(2) == ['', ''] && matcharg(3) == ['', '']
7270+: let @r .= "OK\n"
7271+:else
7272+: let @r .= "FAILED\n"
7273+:endif
7274+:" --- Check that "matchadd()" and "getmatches()" agree on added matches and
7275+:" --- that default values apply.
7276+:let @r .= "*** Test 4: "
7277+:let m1 = matchadd("MyGroup1", "TODO")
7278+:let m2 = matchadd("MyGroup2", "FIXME", 42)
7279+:let m3 = matchadd("MyGroup3", "XXX", 60, 17)
7280+:if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 4}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 42, 'id': 5}, {'group': 'MyGroup3', 'pattern': 'XXX', 'priority': 60, 'id': 17}]
7281+: let @r .= "OK\n"
7282+:else
7283+: let @r .= "FAILED\n"
7284+:endif
7285+:" --- Check that "matchdelete()" deletes the matches defined in the previous
7286+:" --- test correctly.
7287+:let @r .= "*** Test 5: "
7288+:call matchdelete(m1)
7289+:call matchdelete(m2)
7290+:call matchdelete(m3)
7291+:unlet m1
7292+:unlet m2
7293+:unlet m3
7294+:if getmatches() == []
7295+: let @r .= "OK\n"
7296+:else
7297+: let @r .= "FAILED\n"
7298+:endif
[c2aa910]7299+:" --- Check that "matchdelete()" returns 0 if successful and otherwise -1.
[ba61c16]7300+:let @r .= "*** Test 6: "
7301+:let m = matchadd("MyGroup1", "TODO")
7302+:let r1 = matchdelete(m)
7303+:let r2 = matchdelete(42)
7304+:if r1 == 0 && r2 == -1
7305+: let @r .= "OK\n"
7306+:else
7307+: let @r .= "FAILED\n"
7308+:endif
7309+:unlet m
7310+:unlet r1
7311+:unlet r2
7312+:" --- Check that "clearmatches()" clears all matches defined by ":match" and
7313+:" --- "matchadd()".
7314+:let @r .= "*** Test 7: "
7315+:let m1 = matchadd("MyGroup1", "TODO")
7316+:let m2 = matchadd("MyGroup2", "FIXME", 42)
7317+:let m3 = matchadd("MyGroup3", "XXX", 60, 17)
7318+:match MyGroup1 /COFFEE/
7319+:2match MyGroup2 /HUMPPA/
7320+:3match MyGroup3 /VIM/
7321+:call clearmatches()
7322+:if getmatches() == []
7323+: let @r .= "OK\n"
7324+:else
7325+: let @r .= "FAILED\n"
7326+:endif
7327+:unlet m1
7328+:unlet m2
7329+:unlet m3
7330+:" --- Check that "setmatches()" restores a list of matches saved by
7331+:" --- "getmatches()" without changes. (Matches with equal priority must also
7332+:" --- remain in the same order.)
7333+:let @r .= "*** Test 8: "
7334+:let m1 = matchadd("MyGroup1", "TODO")
7335+:let m2 = matchadd("MyGroup2", "FIXME", 42)
7336+:let m3 = matchadd("MyGroup3", "XXX", 60, 17)
7337+:match MyGroup1 /COFFEE/
7338+:2match MyGroup2 /HUMPPA/
7339+:3match MyGroup3 /VIM/
7340+:let ml = getmatches()
7341+:call clearmatches()
7342+:call setmatches(ml)
7343+:if getmatches() == ml
7344+: let @r .= "OK\n"
7345+:else
7346+: let @r .= "FAILED\n"
7347+:endif
7348+:call clearmatches()
7349+:unlet m1
7350+:unlet m2
7351+:unlet m3
7352+:unlet ml
7353+:" --- Check that "setmatches()" will not add two matches with the same ID. The
7354+:" --- expected behaviour (for now) is to add the first match but not the
7355+:" --- second and to return 0 (even though it is a matter of debate whether
[c2aa910]7356+:" --- this can be considered successful behaviour).
[ba61c16]7357+:let @r .= "*** Test 9: "
7358+:let r1 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 10, 'id': 1}])
7359+:if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}] && r1 == 0
7360+: let @r .= "OK\n"
7361+:else
7362+: let @r .= "FAILED\n"
7363+:endif
7364+:call clearmatches()
7365+:unlet r1
[c2aa910]7366+:" --- Check that "setmatches()" returns 0 if successful and otherwise -1.
[ba61c16]7367+:" --- (A range of valid and invalid input values are tried out to generate the
7368+:" --- return values.)
7369+:let @r .= "*** Test 10: "
7370+:let rs1 = setmatches([])
7371+:let rs2 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}])
7372+:call clearmatches()
7373+:let rf1 = setmatches(0)
7374+:let rf2 = setmatches([0])
7375+:let rf3 = setmatches([{'wrong key': 'wrong value'}])
7376+:if rs1 == 0 && rs2 == 0 && rf1 == -1 && rf2 == -1 && rf3 == -1
7377+: let @r .= "OK\n"
7378+:else
7379+: let @r .= "FAILED\n"
7380+:endif
7381+:unlet rs1
7382+:unlet rs2
7383+:unlet rf1
7384+:unlet rf2
7385+:unlet rf3
7386+:highlight clear MyGroup1
7387+:highlight clear MyGroup2
7388+:highlight clear MyGroup3
7389+G"rp
7390+:/^Results/,$wq! test.out
7391+ENDTEST
7392+
7393+Results of test63:
7394diff -Naur vim71.orig/src/testdir/test63.ok vim71/src/testdir/test63.ok
7395--- vim71.orig/src/testdir/test63.ok 1969-12-31 16:00:00.000000000 -0800
[c2aa910]7396+++ vim71/src/testdir/test63.ok 2007-10-16 14:14:07.000000000 -0700
[ba61c16]7397@@ -0,0 +1,11 @@
7398+Results of test63:
7399+*** Test 1: OK
7400+*** Test 2: OK
7401+*** Test 3: OK
7402+*** Test 4: OK
7403+*** Test 5: OK
7404+*** Test 6: OK
7405+*** Test 7: OK
7406+*** Test 8: OK
7407+*** Test 9: OK
7408+*** Test 10: OK
7409diff -Naur vim71.orig/src/testdir/test64.in vim71/src/testdir/test64.in
7410--- vim71.orig/src/testdir/test64.in 1969-12-31 16:00:00.000000000 -0800
[c2aa910]7411+++ vim71/src/testdir/test64.in 2007-10-16 14:14:28.000000000 -0700
7412@@ -0,0 +1,54 @@
[ba61c16]7413+Test for regexp patterns.
7414+
7415+A pattern that gives the expected result produces OK, so that we know it was
7416+actually tried.
7417+
7418+STARTTEST
7419+:so small.vim
7420+:" tl is a List of Lists with:
7421+:" regexp pattern
7422+:" text to test the pattern on
7423+:" expected match (optional)
7424+:" expected submatch 1 (optional)
7425+:" expected submatch 2 (optional)
7426+:" etc.
7427+:" When there is no match use only the first two items.
7428+:let tl = []
7429+:call add(tl, ['b', 'abcdef', 'b'])
7430+:call add(tl, ['bc*', 'abccccdef', 'bcccc'])
7431+:call add(tl, ['bc\{-}', 'abccccdef', 'b'])
7432+:call add(tl, ['bc\{-}\(d\)', 'abccccdef', 'bccccd', 'd'])
7433+:call add(tl, ['x', 'abcdef'])
7434+:"
7435+:for t in tl
7436+: let l = matchlist(t[1], t[0])
7437+:" check the match itself
7438+: if len(l) == 0 && len(t) > 2
7439+: $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", did not match, expected: \"' . t[2] . '\"'
7440+: elseif len(l) > 0 && len(t) == 2
7441+: $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", match: \"' . l[0] . '\", expected no match'
7442+: elseif len(t) > 2 && l[0] != t[2]
7443+: $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", match: \"' . l[0] . '\", expected: \"' . t[2] . '\"'
7444+: else
7445+: $put ='OK'
7446+: endif
7447+: if len(l) > 0
7448+:" check all the nine submatches
7449+: for i in range(1, 9)
7450+: if len(t) <= i + 2
7451+: let e = ''
7452+: else
7453+: let e = t[i + 2]
7454+: endif
7455+: if l[i] != e
7456+: $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", submatch ' . i . ': \"' . l[i] . '\", expected: \"' . e . '\"'
7457+: endif
7458+: endfor
[c2aa910]7459+: unlet i
[ba61c16]7460+: endif
7461+:endfor
[c2aa910]7462+:unlet t tl e l
[ba61c16]7463+:/^Results/,$wq! test.out
7464+ENDTEST
7465+
7466+Results of test64:
7467diff -Naur vim71.orig/src/testdir/test64.ok vim71/src/testdir/test64.ok
7468--- vim71.orig/src/testdir/test64.ok 1969-12-31 16:00:00.000000000 -0800
[c2aa910]7469+++ vim71/src/testdir/test64.ok 2007-10-16 14:14:14.000000000 -0700
[ba61c16]7470@@ -0,0 +1,6 @@
7471+Results of test64:
7472+OK
7473+OK
7474+OK
7475+OK
7476+OK
7477diff -Naur vim71.orig/src/ui.c vim71/src/ui.c
7478--- vim71.orig/src/ui.c 2007-05-07 12:49:09.000000000 -0700
[c2aa910]7479+++ vim71/src/ui.c 2007-10-16 14:14:17.000000000 -0700
[ba61c16]7480@@ -1603,8 +1603,6 @@
7481 #if defined(FEAT_GUI) || defined(FEAT_MOUSE_GPM) \
7482 || defined(FEAT_XCLIPBOARD) || defined(VMS) \
7483 || defined(FEAT_SNIFF) || defined(FEAT_CLIENTSERVER) \
7484- || (defined(FEAT_GUI) && (!defined(USE_ON_FLY_SCROLL) \
7485- || defined(FEAT_MENU))) \
7486 || defined(PROTO)
7487 /*
7488 * Add the given bytes to the input buffer
7489@@ -1630,7 +1628,9 @@
7490 }
7491 #endif
7492
7493-#if (defined(FEAT_XIM) && defined(FEAT_GUI_GTK)) \
7494+#if ((defined(FEAT_XIM) || defined(FEAT_DND)) && defined(FEAT_GUI_GTK)) \
7495+ || defined(FEAT_GUI_MSWIN) \
7496+ || defined(FEAT_GUI_MAC) \
7497 || (defined(FEAT_MBYTE) && defined(FEAT_MBYTE_IME)) \
7498 || (defined(FEAT_GUI) && (!defined(USE_ON_FLY_SCROLL) \
7499 || defined(FEAT_MENU))) \
[c2aa910]7500diff -Naur vim71.orig/src/undo.c vim71/src/undo.c
7501--- vim71.orig/src/undo.c 2007-05-07 12:21:14.000000000 -0700
7502+++ vim71/src/undo.c 2007-10-16 14:14:38.000000000 -0700
7503@@ -76,6 +76,12 @@
7504 * buffer is unloaded.
7505 */
7506
7507+/* Uncomment the next line for including the u_check() function. This warns
7508+ * for errors in the debug information. */
7509+/* #define U_DEBUG 1 */
7510+#define UH_MAGIC 0x18dade /* value for uh_magic when in use */
7511+#define UE_MAGIC 0xabc123 /* value for ue_magic when in use */
7512+
7513 #include "vim.h"
7514
7515 /* See below: use malloc()/free() for memory management. */
7516@@ -113,6 +119,95 @@
7517 */
7518 static int undo_undoes = FALSE;
7519
7520+#ifdef U_DEBUG
7521+/*
7522+ * Check the undo structures for being valid. Print a warning when something
7523+ * looks wrong.
7524+ */
7525+static int seen_b_u_curhead;
7526+static int seen_b_u_newhead;
7527+static int header_count;
7528+
7529+ static void
7530+u_check_tree(u_header_T *uhp,
7531+ u_header_T *exp_uh_next,
7532+ u_header_T *exp_uh_alt_prev)
7533+{
7534+ u_entry_T *uep;
7535+
7536+ if (uhp == NULL)
7537+ return;
7538+ ++header_count;
7539+ if (uhp == curbuf->b_u_curhead && ++seen_b_u_curhead > 1)
7540+ {
7541+ EMSG("b_u_curhead found twice (looping?)");
7542+ return;
7543+ }
7544+ if (uhp == curbuf->b_u_newhead && ++seen_b_u_newhead > 1)
7545+ {
7546+ EMSG("b_u_newhead found twice (looping?)");
7547+ return;
7548+ }
7549+
7550+ if (uhp->uh_magic != UH_MAGIC)
7551+ EMSG("uh_magic wrong (may be using freed memory)");
7552+ else
7553+ {
7554+ /* Check pointers back are correct. */
7555+ if (uhp->uh_next != exp_uh_next)
7556+ {
7557+ EMSG("uh_next wrong");
7558+ smsg((char_u *)"expected: 0x%x, actual: 0x%x",
7559+ exp_uh_next, uhp->uh_next);
7560+ }
7561+ if (uhp->uh_alt_prev != exp_uh_alt_prev)
7562+ {
7563+ EMSG("uh_alt_prev wrong");
7564+ smsg((char_u *)"expected: 0x%x, actual: 0x%x",
7565+ exp_uh_alt_prev, uhp->uh_alt_prev);
7566+ }
7567+
7568+ /* Check the undo tree at this header. */
7569+ for (uep = uhp->uh_entry; uep != NULL; uep = uep->ue_next)
7570+ {
7571+ if (uep->ue_magic != UE_MAGIC)
7572+ {
7573+ EMSG("ue_magic wrong (may be using freed memory)");
7574+ break;
7575+ }
7576+ }
7577+
7578+ /* Check the next alt tree. */
7579+ u_check_tree(uhp->uh_alt_next, uhp->uh_next, uhp);
7580+
7581+ /* Check the next header in this branch. */
7582+ u_check_tree(uhp->uh_prev, uhp, NULL);
7583+ }
7584+}
7585+
7586+ void
7587+u_check(int newhead_may_be_NULL)
7588+{
7589+ seen_b_u_newhead = 0;
7590+ seen_b_u_curhead = 0;
7591+ header_count = 0;
7592+
7593+ u_check_tree(curbuf->b_u_oldhead, NULL, NULL);
7594+
7595+ if (seen_b_u_newhead == 0 && curbuf->b_u_oldhead != NULL
7596+ && !(newhead_may_be_NULL && curbuf->b_u_newhead == NULL))
7597+ EMSGN("b_u_newhead invalid: 0x%x", curbuf->b_u_newhead);
7598+ if (curbuf->b_u_curhead != NULL && seen_b_u_curhead == 0)
7599+ EMSGN("b_u_curhead invalid: 0x%x", curbuf->b_u_curhead);
7600+ if (header_count != curbuf->b_u_numhead)
7601+ {
7602+ EMSG("b_u_numhead invalid");
7603+ smsg((char_u *)"expected: %ld, actual: %ld",
7604+ (long)header_count, (long)curbuf->b_u_numhead);
7605+ }
7606+}
7607+#endif
7608+
7609 /*
7610 * Save the current line for both the "u" and "U" command.
7611 * Returns OK or FAIL.
7612@@ -243,6 +338,9 @@
7613 if (!undo_allowed())
7614 return FAIL;
7615
7616+#ifdef U_DEBUG
7617+ u_check(FALSE);
7618+#endif
7619 #ifdef FEAT_NETBEANS_INTG
7620 /*
7621 * Netbeans defines areas that cannot be modified. Bail out here when
7622@@ -294,6 +392,9 @@
7623 uhp = (u_header_T *)U_ALLOC_LINE((unsigned)sizeof(u_header_T));
7624 if (uhp == NULL)
7625 goto nomem;
7626+#ifdef U_DEBUG
7627+ uhp->uh_magic = UH_MAGIC;
7628+#endif
7629 }
7630 else
7631 uhp = NULL;
7632@@ -316,8 +417,11 @@
7633 {
7634 u_header_T *uhfree = curbuf->b_u_oldhead;
7635
7636- /* If there is no branch only free one header. */
7637- if (uhfree->uh_alt_next == NULL)
7638+ if (uhfree == old_curhead)
7639+ /* Can't reconnect the branch, delete all of it. */
7640+ u_freebranch(curbuf, uhfree, &old_curhead);
7641+ else if (uhfree->uh_alt_next == NULL)
7642+ /* There is no branch, only free one header. */
7643 u_freeheader(curbuf, uhfree, &old_curhead);
7644 else
7645 {
7646@@ -326,6 +430,9 @@
7647 uhfree = uhfree->uh_alt_next;
7648 u_freebranch(curbuf, uhfree, &old_curhead);
7649 }
7650+#ifdef U_DEBUG
7651+ u_check(TRUE);
7652+#endif
7653 }
7654
7655 if (uhp == NULL) /* no undo at all */
7656@@ -478,6 +585,9 @@
7657 uep = (u_entry_T *)U_ALLOC_LINE((unsigned)sizeof(u_entry_T));
7658 if (uep == NULL)
7659 goto nomem;
7660+#ifdef U_DEBUG
7661+ uep->ue_magic = UE_MAGIC;
7662+#endif
7663
7664 uep->ue_size = size;
7665 uep->ue_top = top;
7666@@ -525,6 +635,9 @@
7667 curbuf->b_u_synced = FALSE;
7668 undo_undoes = FALSE;
7669
7670+#ifdef U_DEBUG
7671+ u_check(FALSE);
7672+#endif
7673 return OK;
7674
7675 nomem:
7676@@ -955,6 +1068,9 @@
7677 int empty_buffer; /* buffer became empty */
7678 u_header_T *curhead = curbuf->b_u_curhead;
7679
7680+#ifdef U_DEBUG
7681+ u_check(FALSE);
7682+#endif
7683 old_flags = curhead->uh_flags;
7684 new_flags = (curbuf->b_changed ? UH_CHANGED : 0) +
7685 ((curbuf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0);
7686@@ -1186,6 +1302,9 @@
7687 /* The timestamp can be the same for multiple changes, just use the one of
7688 * the undone/redone change. */
7689 curbuf->b_u_seq_time = curhead->uh_time;
7690+#ifdef U_DEBUG
7691+ u_check(FALSE);
7692+#endif
7693 }
7694
7695 /*
7696@@ -1515,7 +1634,7 @@
7697 }
7698
7699 /*
7700- * Free one header and its entry list and adjust the pointers.
7701+ * Free one header "uhp" and its entry list and adjust the pointers.
7702 */
7703 static void
7704 u_freeheader(buf, uhp, uhpp)
7705@@ -1523,6 +1642,8 @@
7706 u_header_T *uhp;
7707 u_header_T **uhpp; /* if not NULL reset when freeing this header */
7708 {
7709+ u_header_T *uhap;
7710+
7711 /* When there is an alternate redo list free that branch completely,
7712 * because we can never go there. */
7713 if (uhp->uh_alt_next != NULL)
7714@@ -1540,7 +1661,8 @@
7715 if (uhp->uh_prev == NULL)
7716 buf->b_u_newhead = uhp->uh_next;
7717 else
7718- uhp->uh_prev->uh_next = uhp->uh_next;
7719+ for (uhap = uhp->uh_prev; uhap != NULL; uhap = uhap->uh_alt_next)
7720+ uhap->uh_next = uhp->uh_next;
7721
7722 u_freeentries(buf, uhp, uhpp);
7723 }
7724@@ -1585,6 +1707,8 @@
7725 /* Check for pointers to the header that become invalid now. */
7726 if (buf->b_u_curhead == uhp)
7727 buf->b_u_curhead = NULL;
7728+ if (buf->b_u_newhead == uhp)
7729+ buf->b_u_newhead = NULL; /* freeing the newest entry */
7730 if (uhpp != NULL && uhp == *uhpp)
7731 *uhpp = NULL;
7732
7733@@ -1594,6 +1718,9 @@
7734 u_freeentry(uep, uep->ue_size);
7735 }
7736
7737+#ifdef U_DEBUG
7738+ uhp->uh_magic = 0;
7739+#endif
7740 U_FREE_LINE((char_u *)uhp);
7741 --buf->b_u_numhead;
7742 }
7743@@ -1609,6 +1736,9 @@
7744 while (n > 0)
7745 U_FREE_LINE(uep->ue_array[--n]);
7746 U_FREE_LINE((char_u *)uep->ue_array);
7747+#ifdef U_DEBUG
7748+ uep->ue_magic = 0;
7749+#endif
7750 U_FREE_LINE((char_u *)uep);
7751 }
7752
[ba61c16]7753diff -Naur vim71.orig/src/version.c vim71/src/version.c
7754--- vim71.orig/src/version.c 2007-05-12 03:23:44.000000000 -0700
[c2aa910]7755+++ vim71/src/version.c 2007-10-16 14:14:41.000000000 -0700
7756@@ -667,6 +667,256 @@
[ba61c16]7757 static int included_patches[] =
7758 { /* Add new patch number below this line */
7759 /**/
[c2aa910]7760+ 140,
7761+/**/
7762+ 139,
7763+/**/
7764+ 138,
7765+/**/
7766+ 137,
7767+/**/
7768+ 136,
7769+/**/
7770+ 135,
7771+/**/
7772+ 133,
7773+/**/
7774+ 132,
7775+/**/
7776+ 131,
7777+/**/
7778+ 130,
7779+/**/
7780+ 127,
7781+/**/
7782+ 125,
7783+/**/
7784+ 123,
7785+/**/
7786+ 122,
7787+/**/
7788+ 121,
7789+/**/
7790+ 120,
7791+/**/
7792+ 119,
7793+/**/
7794+ 118,
7795+/**/
7796+ 117,
7797+/**/
7798+ 116,
7799+/**/
7800+ 115,
7801+/**/
7802+ 114,
7803+/**/
7804+ 113,
7805+/**/
7806+ 112,
7807+/**/
7808+ 111,
7809+/**/
7810+ 110,
7811+/**/
7812+ 109,
7813+/**/
7814+ 108,
7815+/**/
7816+ 107,
7817+/**/
7818+ 106,
7819+/**/
7820+ 105,
7821+/**/
7822+ 104,
7823+/**/
7824+ 103,
7825+/**/
7826+ 102,
7827+/**/
7828+ 101,
7829+/**/
7830+ 100,
7831+/**/
7832+ 99,
7833+/**/
7834+ 98,
7835+/**/
7836+ 97,
7837+/**/
7838+ 96,
7839+/**/
7840+ 95,
7841+/**/
[ba61c16]7842+ 94,
7843+/**/
7844+ 93,
7845+/**/
7846+ 90,
7847+/**/
7848+ 89,
7849+/**/
7850+ 87,
7851+/**/
7852+ 86,
7853+/**/
7854+ 85,
7855+/**/
7856+ 84,
7857+/**/
7858+ 83,
7859+/**/
7860+ 82,
7861+/**/
7862+ 81,
7863+/**/
7864+ 79,
7865+/**/
7866+ 78,
7867+/**/
7868+ 77,
7869+/**/
7870+ 76,
7871+/**/
7872+ 75,
7873+/**/
7874+ 74,
7875+/**/
7876+ 73,
7877+/**/
7878+ 71,
7879+/**/
7880+ 69,
7881+/**/
7882+ 68,
7883+/**/
7884+ 67,
7885+/**/
7886+ 66,
7887+/**/
7888+ 64,
7889+/**/
7890+ 63,
7891+/**/
7892+ 62,
7893+/**/
7894+ 61,
7895+/**/
7896+ 60,
7897+/**/
7898+ 59,
7899+/**/
7900+ 58,
7901+/**/
7902+ 57,
7903+/**/
7904+ 56,
7905+/**/
7906+ 55,
7907+/**/
7908+ 54,
7909+/**/
7910+ 53,
7911+/**/
7912+ 52,
7913+/**/
7914+ 51,
7915+/**/
7916+ 50,
7917+/**/
7918+ 49,
7919+/**/
7920+ 48,
7921+/**/
7922+ 47,
7923+/**/
7924+ 46,
7925+/**/
7926+ 45,
7927+/**/
7928+ 44,
7929+/**/
7930+ 43,
7931+/**/
7932+ 42,
7933+/**/
7934+ 40,
7935+/**/
7936+ 39,
7937+/**/
7938+ 38,
7939+/**/
7940+ 37,
7941+/**/
7942+ 36,
7943+/**/
7944+ 35,
7945+/**/
7946+ 34,
7947+/**/
7948+ 33,
7949+/**/
7950+ 32,
7951+/**/
7952+ 31,
7953+/**/
7954+ 30,
7955+/**/
7956+ 29,
7957+/**/
7958+ 28,
7959+/**/
7960+ 27,
7961+/**/
7962+ 26,
7963+/**/
7964+ 25,
7965+/**/
7966+ 24,
7967+/**/
7968+ 23,
7969+/**/
7970+ 22,
7971+/**/
7972+ 21,
7973+/**/
7974+ 20,
7975+/**/
7976+ 19,
7977+/**/
7978+ 18,
7979+/**/
7980+ 17,
7981+/**/
7982+ 16,
7983+/**/
7984+ 15,
7985+/**/
7986+ 14,
7987+/**/
7988+ 13,
7989+/**/
7990+ 12,
7991+/**/
7992+ 11,
7993+/**/
7994+ 10,
7995+/**/
7996+ 9,
7997+/**/
7998+ 8,
7999+/**/
8000+ 6,
8001+/**/
8002+ 5,
8003+/**/
8004+ 4,
8005+/**/
8006+ 2,
8007+/**/
8008+ 1,
8009+/**/
8010 0
8011 };
8012
8013diff -Naur vim71.orig/src/vim.h vim71/src/vim.h
8014--- vim71.orig/src/vim.h 2007-05-12 02:53:29.000000000 -0700
[c2aa910]8015+++ vim71/src/vim.h 2007-10-16 14:14:09.000000000 -0700
[ba61c16]8016@@ -1380,8 +1380,14 @@
8017 #endif
8018
8019 #ifdef FEAT_MBYTE
8020-# define MB_STRICMP(d, s) (has_mbyte ? mb_strnicmp((char_u *)(d), (char_u *)(s), (int)MAXCOL) : STRICMP((d), (s)))
8021-# define MB_STRNICMP(d, s, n) (has_mbyte ? mb_strnicmp((char_u *)(d), (char_u *)(s), (int)(n)) : STRNICMP((d), (s), (n)))
8022+/* We need to call mb_stricmp() even when we aren't dealing with a multi-byte
8023+ * encoding because mb_stricmp() takes care of all ascii and non-ascii
8024+ * encodings, including characters with umluats in latin1, etc., while
8025+ * STRICMP() only handles the system locale version, which often does not
8026+ * handle non-ascii properly. */
8027+
8028+# define MB_STRICMP(d, s) mb_strnicmp((char_u *)(d), (char_u *)(s), (int)MAXCOL)
8029+# define MB_STRNICMP(d, s, n) mb_strnicmp((char_u *)(d), (char_u *)(s), (int)(n))
8030 #else
8031 # define MB_STRICMP(d, s) STRICMP((d), (s))
8032 # define MB_STRNICMP(d, s, n) STRNICMP((d), (s), (n))
8033diff -Naur vim71.orig/src/vimtutor vim71/src/vimtutor
8034--- vim71.orig/src/vimtutor 2004-06-07 07:32:27.000000000 -0700
[c2aa910]8035+++ vim71/src/vimtutor 2007-10-16 14:14:06.000000000 -0700
[ba61c16]8036@@ -39,18 +39,22 @@
8037 # remove the copy of the tutor on exit
8038 trap "rm -rf $TODELETE" 0 1 2 3 9 11 13 15
8039
8040-# Vim could be called "vim" or "vi". Also check for "vim6", for people who
8041-# have Vim 5.x installed as "vim" and Vim 6.0 as "vim6".
8042-testvim=`which vim6 2>/dev/null`
8043-if test -f "$testvim"; then
8044- VIM=vim6
8045-else
8046- testvim=`which vim`
8047+# Vim could be called "vim" or "vi". Also check for "vimN", for people who
8048+# have Vim installed with its version number.
8049+# We anticipate up to a future Vim 8 version :-).
8050+seq="vim vim8 vim75 vim74 vim73 vim72 vim71 vim70 vim7 vim6 vi"
8051+for i in $seq; do
8052+ testvim=`which $i 2>/dev/null`
8053 if test -f "$testvim"; then
8054- VIM=vim
8055- else
8056- VIM=vi
8057+ VIM=$i
8058+ break
8059 fi
8060+done
8061+
8062+# When no Vim version was found fall back to "vim", you'll get an error message
8063+# below.
8064+if test -z "$VIM"; then
8065+ VIM=vim
8066 fi
8067
8068 # Use Vim to copy the tutor, it knows the value of $VIMRUNTIME
8069diff -Naur vim71.orig/src/window.c vim71/src/window.c
8070--- vim71.orig/src/window.c 2007-05-07 12:25:30.000000000 -0700
[c2aa910]8071+++ vim71/src/window.c 2007-10-16 14:14:31.000000000 -0700
[ba61c16]8072@@ -75,6 +75,7 @@
8073 static win_T *restore_snapshot_rec __ARGS((frame_T *sn, frame_T *fr));
8074
8075 #endif /* FEAT_WINDOWS */
8076+
8077 static win_T *win_alloc __ARGS((win_T *after));
8078 static void win_new_height __ARGS((win_T *, int));
8079
[c2aa910]8080@@ -583,7 +584,7 @@
8081 ++no_mapping;
8082 ++allow_keys; /* no mapping for xchar, but allow key codes */
8083 if (xchar == NUL)
8084- xchar = safe_vgetc();
8085+ xchar = plain_vgetc();
8086 #ifdef FEAT_LANGMAP
8087 LANGMAP_ADJUST(xchar, TRUE);
8088 #endif
[ba61c16]8089@@ -732,7 +733,6 @@
8090 if (flags & WSP_VERT)
8091 {
8092 layout = FR_ROW;
8093- do_equal = (p_ea && new_size == 0 && *p_ead != 'v');
8094
8095 /*
8096 * Check if we are able to split the current window and compute its
8097@@ -769,16 +769,31 @@
8098 * instead, if possible. */
8099 if (oldwin->w_p_wfw)
8100 win_setwidth_win(oldwin->w_width + new_size, oldwin);
8101+
8102+ /* Only make all windows the same width if one of them (except oldwin)
8103+ * is wider than one of the split windows. */
8104+ if (!do_equal && p_ea && size == 0 && *p_ead != 'v'
8105+ && oldwin->w_frame->fr_parent != NULL)
8106+ {
8107+ frp = oldwin->w_frame->fr_parent->fr_child;
8108+ while (frp != NULL)
8109+ {
8110+ if (frp->fr_win != oldwin && frp->fr_win != NULL
8111+ && (frp->fr_win->w_width > new_size
8112+ || frp->fr_win->w_width > oldwin->w_width
8113+ - new_size - STATUS_HEIGHT))
8114+ {
8115+ do_equal = TRUE;
8116+ break;
8117+ }
8118+ frp = frp->fr_next;
8119+ }
8120+ }
8121 }
8122 else
8123 #endif
8124 {
8125 layout = FR_COL;
8126- do_equal = (p_ea && new_size == 0
8127-#ifdef FEAT_VERTSPLIT
8128- && *p_ead != 'h'
8129-#endif
8130- );
8131
8132 /*
8133 * Check if we are able to split the current window and compute its
8134@@ -831,6 +846,29 @@
8135 if (need_status)
8136 oldwin_height -= STATUS_HEIGHT;
8137 }
8138+
8139+ /* Only make all windows the same height if one of them (except oldwin)
8140+ * is higher than one of the split windows. */
8141+ if (!do_equal && p_ea && size == 0
8142+#ifdef FEAT_VERTSPLIT
8143+ && *p_ead != 'h'
8144+#endif
8145+ && oldwin->w_frame->fr_parent != NULL)
8146+ {
8147+ frp = oldwin->w_frame->fr_parent->fr_child;
8148+ while (frp != NULL)
8149+ {
8150+ if (frp->fr_win != oldwin && frp->fr_win != NULL
8151+ && (frp->fr_win->w_height > new_size
8152+ || frp->fr_win->w_height > oldwin_height - new_size
8153+ - STATUS_HEIGHT))
8154+ {
8155+ do_equal = TRUE;
8156+ break;
8157+ }
8158+ frp = frp->fr_next;
8159+ }
8160+ }
8161 }
8162
8163 /*
[c2aa910]8164@@ -1253,7 +1291,7 @@
8165 * Don't execute autocommands while creating the windows. Must do that
8166 * when putting the buffers in the windows.
8167 */
8168- ++autocmd_block;
8169+ block_autocmds();
8170 #endif
8171
8172 /* todo is number of windows left to create */
8173@@ -1275,7 +1313,7 @@
8174 }
8175
8176 #ifdef FEAT_AUTOCMD
8177- --autocmd_block;
8178+ unblock_autocmds();
8179 #endif
8180
8181 /* return actual number of windows */
[ba61c16]8182@@ -2120,7 +2158,7 @@
8183 if (wp->w_p_pvw || bt_quickfix(wp->w_buffer))
8184 {
8185 /*
8186- * The cursor goes to the preview or the quickfix window, try
8187+ * If the cursor goes to the preview or the quickfix window, try
8188 * finding another window to go to.
8189 */
8190 for (;;)
8191@@ -2307,7 +2345,6 @@
8192 frame_T *frp, *frp2, *frp3;
8193 frame_T *frp_close = win->w_frame;
8194 win_T *wp;
8195- int old_size = 0;
8196
8197 /*
8198 * If there is only one window there is nothing to remove.
8199@@ -2328,33 +2365,77 @@
8200 if (frp_close->fr_parent->fr_layout == FR_COL)
8201 {
8202 #endif
8203- /* When 'winfixheight' is set, remember its old size and restore
8204- * it later (it's a simplistic solution...). Don't do this if the
8205- * window will occupy the full height of the screen. */
8206- if (frp2->fr_win != NULL
8207- && (frp2->fr_next != NULL || frp2->fr_prev != NULL)
8208- && frp2->fr_win->w_p_wfh)
8209- old_size = frp2->fr_win->w_height;
8210+ /* When 'winfixheight' is set, try to find another frame in the column
8211+ * (as close to the closed frame as possible) to distribute the height
8212+ * to. */
8213+ if (frp2->fr_win != NULL && frp2->fr_win->w_p_wfh)
8214+ {
8215+ frp = frp_close->fr_prev;
8216+ frp3 = frp_close->fr_next;
8217+ while (frp != NULL || frp3 != NULL)
8218+ {
8219+ if (frp != NULL)
8220+ {
8221+ if (frp->fr_win != NULL && !frp->fr_win->w_p_wfh)
8222+ {
8223+ frp2 = frp;
8224+ wp = frp->fr_win;
8225+ break;
8226+ }
8227+ frp = frp->fr_prev;
8228+ }
8229+ if (frp3 != NULL)
8230+ {
8231+ if (frp3->fr_win != NULL && !frp3->fr_win->w_p_wfh)
8232+ {
8233+ frp2 = frp3;
8234+ wp = frp3->fr_win;
8235+ break;
8236+ }
8237+ frp3 = frp3->fr_next;
8238+ }
8239+ }
8240+ }
8241 frame_new_height(frp2, frp2->fr_height + frp_close->fr_height,
8242 frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE);
8243- if (old_size != 0)
8244- win_setheight_win(old_size, frp2->fr_win);
8245 #ifdef FEAT_VERTSPLIT
8246 *dirp = 'v';
8247 }
8248 else
8249 {
8250- /* When 'winfixwidth' is set, remember its old size and restore
8251- * it later (it's a simplistic solution...). Don't do this if the
8252- * window will occupy the full width of the screen. */
8253- if (frp2->fr_win != NULL
8254- && (frp2->fr_next != NULL || frp2->fr_prev != NULL)
8255- && frp2->fr_win->w_p_wfw)
8256- old_size = frp2->fr_win->w_width;
8257+ /* When 'winfixwidth' is set, try to find another frame in the column
8258+ * (as close to the closed frame as possible) to distribute the width
8259+ * to. */
8260+ if (frp2->fr_win != NULL && frp2->fr_win->w_p_wfw)
8261+ {
8262+ frp = frp_close->fr_prev;
8263+ frp3 = frp_close->fr_next;
8264+ while (frp != NULL || frp3 != NULL)
8265+ {
8266+ if (frp != NULL)
8267+ {
8268+ if (frp->fr_win != NULL && !frp->fr_win->w_p_wfw)
8269+ {
8270+ frp2 = frp;
8271+ wp = frp->fr_win;
8272+ break;
8273+ }
8274+ frp = frp->fr_prev;
8275+ }
8276+ if (frp3 != NULL)
8277+ {
8278+ if (frp3->fr_win != NULL && !frp3->fr_win->w_p_wfw)
8279+ {
8280+ frp2 = frp3;
8281+ wp = frp3->fr_win;
8282+ break;
8283+ }
8284+ frp3 = frp3->fr_next;
8285+ }
8286+ }
8287+ }
8288 frame_new_width(frp2, frp2->fr_width + frp_close->fr_width,
8289 frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE);
8290- if (old_size != 0)
8291- win_setwidth_win(old_size, frp2->fr_win);
8292 *dirp = 'h';
8293 }
8294 #endif
[c2aa910]8295@@ -3334,7 +3415,7 @@
8296 * Don't execute autocommands while creating the tab pages. Must do that
8297 * when putting the buffers in the windows.
8298 */
8299- ++autocmd_block;
8300+ block_autocmds();
8301 #endif
8302
8303 for (todo = count - 1; todo > 0; --todo)
8304@@ -3342,7 +3423,7 @@
8305 break;
8306
[ba61c16]8307 #ifdef FEAT_AUTOCMD
[c2aa910]8308- --autocmd_block;
8309+ unblock_autocmds();
8310 #endif
8311
8312 /* return actual number of tab pages */
8313@@ -4081,7 +4162,7 @@
8314 /* Don't execute autocommands while the window is not properly
8315 * initialized yet. gui_create_scrollbar() may trigger a FocusGained
8316 * event. */
8317- ++autocmd_block;
8318+ block_autocmds();
8319 #endif
8320 /*
8321 * link the window in the window list
8322@@ -4126,7 +4207,11 @@
8323 foldInitWin(newwin);
[ba61c16]8324 #endif
[c2aa910]8325 #ifdef FEAT_AUTOCMD
8326- --autocmd_block;
8327+ unblock_autocmds();
8328+#endif
[ba61c16]8329+#ifdef FEAT_SEARCH_EXTRA
8330+ newwin->w_match_head = NULL;
8331+ newwin->w_next_match_id = 4;
[c2aa910]8332 #endif
[ba61c16]8333 }
8334 return newwin;
[c2aa910]8335@@ -4147,7 +4232,7 @@
8336 #ifdef FEAT_AUTOCMD
8337 /* Don't execute autocommands while the window is halfway being deleted.
8338 * gui_mch_destroy_scrollbar() may trigger a FocusGained event. */
8339- ++autocmd_block;
8340+ block_autocmds();
8341 #endif
8342
8343 #ifdef FEAT_MZSCHEME
[ba61c16]8344@@ -4185,11 +4270,11 @@
8345 vim_free(wp->w_tagstack[i].tagname);
8346
8347 vim_free(wp->w_localdir);
8348+
8349 #ifdef FEAT_SEARCH_EXTRA
8350- vim_free(wp->w_match[0].regprog);
8351- vim_free(wp->w_match[1].regprog);
8352- vim_free(wp->w_match[2].regprog);
8353+ clear_matches(wp);
8354 #endif
8355+
8356 #ifdef FEAT_JUMPLIST
8357 free_jumplist(wp);
8358 #endif
[c2aa910]8359@@ -4210,7 +4295,7 @@
8360 vim_free(wp);
8361
8362 #ifdef FEAT_AUTOCMD
8363- --autocmd_block;
8364+ unblock_autocmds();
8365 #endif
8366 }
8367
8368@@ -5438,6 +5523,7 @@
8369 {
8370 EMSG(_(e_noroom));
8371 p_ch = old_p_ch;
8372+ curtab->tp_ch_used = p_ch;
8373 cmdline_row = Rows - p_ch;
8374 break;
8375 }
8376@@ -6174,3 +6260,175 @@
[ba61c16]8377 return FALSE;
8378 }
8379 #endif
8380+
8381+#if defined(FEAT_SEARCH_EXTRA) || defined(PROTO)
8382+/*
8383+ * Add match to the match list of window 'wp'. The pattern 'pat' will be
8384+ * highligted with the group 'grp' with priority 'prio'.
8385+ * Optionally, a desired ID 'id' can be specified (greater than or equal to 1).
8386+ * If no particular ID is desired, -1 must be specified for 'id'.
8387+ * Return ID of added match, -1 on failure.
8388+ */
8389+ int
8390+match_add(wp, grp, pat, prio, id)
8391+ win_T *wp;
8392+ char_u *grp;
8393+ char_u *pat;
8394+ int prio;
8395+ int id;
8396+{
8397+ matchitem_T *cur;
8398+ matchitem_T *prev;
8399+ matchitem_T *m;
8400+ int hlg_id;
8401+ regprog_T *regprog;
8402+
8403+ if (*grp == NUL || *pat == NUL)
8404+ return -1;
8405+ if (id < -1 || id == 0)
8406+ {
8407+ EMSGN("E799: Invalid ID: %ld (must be greater than or equal to 1)", id);
8408+ return -1;
8409+ }
8410+ if (id != -1)
8411+ {
8412+ cur = wp->w_match_head;
8413+ while (cur != NULL)
8414+ {
8415+ if (cur->id == id)
8416+ {
8417+ EMSGN("E801: ID already taken: %ld", id);
8418+ return -1;
8419+ }
8420+ cur = cur->next;
8421+ }
8422+ }
8423+ if ((hlg_id = syn_namen2id(grp, STRLEN(grp))) == 0)
8424+ {
8425+ EMSG2(_(e_nogroup), grp);
8426+ return -1;
8427+ }
8428+ if ((regprog = vim_regcomp(pat, RE_MAGIC)) == NULL)
8429+ {
8430+ EMSG2(_(e_invarg2), pat);
8431+ return -1;
8432+ }
8433+
8434+ /* Find available match ID. */
8435+ while (id == -1)
8436+ {
8437+ cur = wp->w_match_head;
8438+ while (cur != NULL && cur->id != wp->w_next_match_id)
8439+ cur = cur->next;
8440+ if (cur == NULL)
8441+ id = wp->w_next_match_id;
8442+ wp->w_next_match_id++;
8443+ }
8444+
8445+ /* Build new match. */
8446+ m = (matchitem_T *)alloc(sizeof(matchitem_T));
8447+ m->id = id;
8448+ m->priority = prio;
8449+ m->pattern = vim_strsave(pat);
8450+ m->hlg_id = hlg_id;
8451+ m->match.regprog = regprog;
8452+ m->match.rmm_ic = FALSE;
8453+ m->match.rmm_maxcol = 0;
8454+
8455+ /* Insert new match. The match list is in ascending order with regard to
8456+ * the match priorities. */
8457+ cur = wp->w_match_head;
8458+ prev = cur;
8459+ while (cur != NULL && prio >= cur->priority)
8460+ {
8461+ prev = cur;
8462+ cur = cur->next;
8463+ }
8464+ if (cur == prev)
8465+ wp->w_match_head = m;
8466+ else
8467+ prev->next = m;
8468+ m->next = cur;
8469+
8470+ redraw_later(SOME_VALID);
8471+ return id;
8472+}
8473+
8474+/*
8475+ * Delete match with ID 'id' in the match list of window 'wp'.
8476+ * Print error messages if 'perr' is TRUE.
8477+ */
8478+ int
8479+match_delete(wp, id, perr)
8480+ win_T *wp;
8481+ int id;
8482+ int perr;
8483+{
8484+ matchitem_T *cur = wp->w_match_head;
8485+ matchitem_T *prev = cur;
8486+
8487+ if (id < 1)
8488+ {
8489+ if (perr == TRUE)
8490+ EMSGN("E802: Invalid ID: %ld (must be greater than or equal to 1)",
8491+ id);
8492+ return -1;
8493+ }
8494+ while (cur != NULL && cur->id != id)
8495+ {
8496+ prev = cur;
8497+ cur = cur->next;
8498+ }
8499+ if (cur == NULL)
8500+ {
8501+ if (perr == TRUE)
8502+ EMSGN("E803: ID not found: %ld", id);
8503+ return -1;
8504+ }
8505+ if (cur == prev)
8506+ wp->w_match_head = cur->next;
8507+ else
8508+ prev->next = cur->next;
8509+ vim_free(cur->match.regprog);
8510+ vim_free(cur->pattern);
8511+ vim_free(cur);
8512+ redraw_later(SOME_VALID);
8513+ return 0;
8514+}
8515+
8516+/*
8517+ * Delete all matches in the match list of window 'wp'.
8518+ */
8519+ void
8520+clear_matches(wp)
8521+ win_T *wp;
8522+{
8523+ matchitem_T *m;
8524+
8525+ while (wp->w_match_head != NULL)
8526+ {
8527+ m = wp->w_match_head->next;
8528+ vim_free(wp->w_match_head->match.regprog);
8529+ vim_free(wp->w_match_head->pattern);
8530+ vim_free(wp->w_match_head);
8531+ wp->w_match_head = m;
8532+ }
8533+ redraw_later(SOME_VALID);
8534+}
8535+
8536+/*
8537+ * Get match from ID 'id' in window 'wp'.
8538+ * Return NULL if match not found.
8539+ */
8540+ matchitem_T *
8541+get_match(wp, id)
8542+ win_T *wp;
8543+ int id;
8544+{
8545+ matchitem_T *cur = wp->w_match_head;
8546+
8547+ while (cur != NULL && cur->id != id)
8548+ cur = cur->next;
8549+ return cur;
8550+}
8551+#endif
Note: See TracBrowser for help on using the repository browser.