source: patches/vim-7.1-fixes-3.patch@ 88b8876

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

Updated Vim 3.1 Patch to -3.

  • Property mode set to 100644
File size: 172.9 KB
RevLine 
[ba61c16]1Submitted By: Jim Gifford (jim at linuxfromscratch dot org)
2Date: 09-03-2007
3Initial Package Version: 7.1
4Origin: Upstream
5Upstream Status: Applied
6Description: Contains all upstream patches up to 7.1.094
7 The following patches were skipped
8 0 003 007 041 065 070 072 080 088 091 092
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
12+++ vim71/runtime/doc/change.txt 2007-09-03 22:13:15.000000000 -0700
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
26+++ vim71/runtime/doc/eval.txt 2007-09-03 22:13:43.000000000 -0700
27@@ -1,4 +1,4 @@
28-*eval.txt* For Vim version 7.1. Last change: 2007 May 11
29+*eval.txt* For Vim version 7.1. Last change: 2007 Jul 25
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
41@@ -1622,6 +1623,7 @@
42 getline( {lnum}) String line {lnum} of current buffer
43 getline( {lnum}, {end}) List lines {lnum} to {end} of current buffer
44 getloclist({nr}) List list of location list items
45+getmatches() List list of current matches
46 getpos( {expr}) List position of cursor, mark, etc.
47 getqflist() List list of quickfix items
48 getreg( [{regname} [, 1]]) String contents of register
49@@ -1676,7 +1678,10 @@
50 String check for mappings matching {name}
51 match( {expr}, {pat}[, {start}[, {count}]])
52 Number position where {pat} matches in {expr}
53+matchadd( {group}, {pattern}[, {priority}[, {id}]])
54+ Number highlight {pattern} with {group}
55 matcharg( {nr}) List arguments of |:match|
56+matchdelete( {id}) Number delete match identified by {id}
57 matchend( {expr}, {pat}[, {start}[, {count}]])
58 Number position where {pat} ends in {expr}
59 matchlist( {expr}, {pat}[, {start}[, {count}]])
60@@ -1731,6 +1736,7 @@
61 setline( {lnum}, {line}) Number set line {lnum} to {line}
62 setloclist( {nr}, {list}[, {action}])
63 Number modify location list using {list}
64+setmatches( {list}) Number restore a list of matches
65 setpos( {expr}, {list}) none set the {expr} position to {list}
66 setqflist( {list}[, {action}]) Number modify quickfix list using {list}
67 setreg( {n}, {v}[, {opt}]) Number set register to value and type
68@@ -2012,6 +2018,10 @@
69 feature, -1 is returned.
70 See |C-indenting|.
71
72+clearmatches() *clearmatches()*
73+ Clears all matches previously defined by |matchadd()| and the
74+ |:match| commands.
75+
76 *col()*
77 col({expr}) The result is a Number, which is the byte index of the column
78 position given with {expr}. The accepted positions are:
79@@ -2020,6 +2030,10 @@
80 number of characters in the cursor line plus one)
81 'x position of mark x (if the mark is not set, 0 is
82 returned)
83+ Additionally {expr} can be [lnum, col]: a |List| with the line
84+ and column number. Most useful when the column is "$", to get
85+ the las column of a specific line. When "lnum" or "col" is
86+ out of range then col() returns zero.
87 To get the line number use |line()|. To get both use
88 |getpos()|.
89 For the screen column position use |virtcol()|.
90@@ -2824,6 +2838,8 @@
91 given file {fname}.
92 If {fname} is a directory, 0 is returned.
93 If the file {fname} can't be found, -1 is returned.
94+ If the size of {fname} is too big to fit in a Number then -2
95+ is returned.
96
97 getfontname([{name}]) *getfontname()*
98 Without an argument returns the name of the normal font being
99@@ -2912,6 +2928,28 @@
100 returned. For an invalid window number {nr}, an empty list is
101 returned. Otherwise, same as getqflist().
102
103+getmatches() *getmatches()*
104+ Returns a |List| with all matches previously defined by
105+ |matchadd()| and the |:match| commands. |getmatches()| is
106+ useful in combination with |setmatches()|, as |setmatches()|
107+ can restore a list of matches saved by |getmatches()|.
108+ Example: >
109+ :echo getmatches()
110+< [{'group': 'MyGroup1', 'pattern': 'TODO',
111+ 'priority': 10, 'id': 1}, {'group': 'MyGroup2',
112+ 'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
113+ :let m = getmatches()
114+ :call clearmatches()
115+ :echo getmatches()
116+< [] >
117+ :call setmatches(m)
118+ :echo getmatches()
119+< [{'group': 'MyGroup1', 'pattern': 'TODO',
120+ 'priority': 10, 'id': 1}, {'group': 'MyGroup2',
121+ 'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
122+ :unlet m
123+<
124+
125 getqflist() *getqflist()*
126 Returns a list with all the current quickfix errors. Each
127 list item is a dictionary with these entries:
128@@ -3616,6 +3654,44 @@
129 the pattern. 'smartcase' is NOT used. The matching is always
130 done like 'magic' is set and 'cpoptions' is empty.
131
132+ *matchadd()* *E798* *E799* *E801*
133+matchadd({group}, {pattern}[, {priority}[, {id}]])
134+ Defines a pattern to be highlighted in the current window (a
135+ "match"). It will be highlighted with {group}. Returns an
136+ identification number (ID), which can be used to delete the
137+ match using |matchdelete()|.
138+
139+ The optional {priority} argument assigns a priority to the
140+ match. A match with a high priority will have its
141+ highlighting overrule that of a match with a lower priority.
142+ A priority is specified as an integer (negative numbers are no
143+ exception). If the {priority} argument is not specified, the
144+ default priority is 10. The priority of 'hlsearch' is zero,
145+ hence all matches with a priority greater than zero will
146+ overrule it. Syntax highlighting (see 'syntax') is a separate
147+ mechanism, and regardless of the chosen priority a match will
148+ always overrule syntax highlighting.
149+
150+ The optional {id} argument allows the request for a specific
151+ match ID. If a specified ID is already taken, an error
152+ message will appear and the match will not be added. An ID
153+ is specified as a positive integer (zero excluded). IDs 1, 2
154+ and 3 are reserved for |:match|, |:2match| and |:3match|,
155+ respectively. If the {id} argument is not specified,
156+ |matchadd()| automatically chooses a free ID.
157+
158+ The number of matches is not limited, as it is the case with
159+ the |:match| commands.
160+
161+ Example: >
162+ :highlight MyGroup ctermbg=green guibg=green
163+ :let m = matchadd("MyGroup", "TODO")
164+< Deletion of the pattern: >
165+ :call matchdelete(m)
166+
167+< A list of matches defined by |matchadd()| and |:match| are
168+ available from |getmatches()|. All matches can be deleted in
169+ one operation by |clearmatches()|.
170
171 matcharg({nr}) *matcharg()*
172 Selects the {nr} match item, as set with a |:match|,
173@@ -3625,8 +3701,15 @@
174 The pattern used.
175 When {nr} is not 1, 2 or 3 returns an empty |List|.
176 When there is no match item set returns ['', ''].
177- This is usef to save and restore a |:match|.
178-
179+ This is useful to save and restore a |:match|.
180+ Highlighting matches using the |:match| commands are limited
181+ to three matches. |matchadd()| does not have this limitation.
182+
183+matchdelete({id}) *matchdelete()* *E802* *E803*
184+ Deletes a match with ID {id} previously defined by |matchadd()|
185+ or one of the |:match| commands. Returns 0 if succesfull,
186+ otherwise -1. See example for |matchadd()|. All matches can
187+ be deleted in one operation by |clearmatches()|.
188
189 matchend({expr}, {pat}[, {start}[, {count}]]) *matchend()*
190 Same as match(), but return the index of first character after
191@@ -4379,7 +4462,13 @@
192 When {nr} is zero the current window is used. For a location
193 list window, the displayed location list is modified. For an
194 invalid window number {nr}, -1 is returned.
195- Otherwise, same as setqflist().
196+ Otherwise, same as |setqflist()|.
197+ Also see |location-list|.
198+
199+setmatches({list}) *setmatches()*
200+ Restores a list of matches saved by |getmatches()|. Returns 0
201+ if succesfull, otherwise -1. All current matches are cleared
202+ before the list is restored. See example for |getmatches()|.
203
204 *setpos()*
205 setpos({expr}, {list})
206@@ -5022,14 +5111,12 @@
207 position, the returned Number will be the column at the end of
208 the <Tab>. For example, for a <Tab> in column 1, with 'ts'
209 set to 8, it returns 8.
210- For the use of {expr} see |col()|. Additionally you can use
211- [lnum, col]: a |List| with the line and column number. When
212- "lnum" or "col" is out of range then virtcol() returns zero.
213- When 'virtualedit' is used it can be [lnum, col, off], where
214+ For the byte position use |col()|.
215+ For the use of {expr} see |col()|.
216+ When 'virtualedit' is used {expr} can be [lnum, col, off], where
217 "off" is the offset in screen columns from the start of the
218 character. E.g., a position within a <Tab> or after the last
219 character.
220- For the byte position use |col()|.
221 When Virtual editing is active in the current mode, a position
222 beyond the end of the line can be returned. |'virtualedit'|
223 The accepted positions are:
224diff -Naur vim71.orig/runtime/doc/options.txt vim71/runtime/doc/options.txt
225--- vim71.orig/runtime/doc/options.txt 2007-05-12 03:18:47.000000000 -0700
226+++ vim71/runtime/doc/options.txt 2007-09-03 22:14:47.000000000 -0700
227@@ -1,4 +1,4 @@
228-*options.txt* For Vim version 7.1. Last change: 2007 May 11
229+*options.txt* For Vim version 7.1. Last change: 2007 Aug 10
230
231
232 VIM REFERENCE MANUAL by Bram Moolenaar
233@@ -2415,8 +2415,8 @@
234 When mixing vertically and horizontally split windows, a minimal size
235 is computed and some windows may be larger if there is room. The
236 'eadirection' option tells in which direction the size is affected.
237- Changing the height of a window can be avoided by setting
238- 'winfixheight'.
239+ Changing the height and width of a window can be avoided by setting
240+ 'winfixheight' and 'winfixwidth', respectively.
241
242 *'equalprg'* *'ep'*
243 'equalprg' 'ep' string (default "")
244diff -Naur vim71.orig/runtime/doc/pattern.txt vim71/runtime/doc/pattern.txt
245--- vim71.orig/runtime/doc/pattern.txt 2007-05-12 03:18:47.000000000 -0700
246+++ vim71/runtime/doc/pattern.txt 2007-09-03 22:13:43.000000000 -0700
247@@ -1212,7 +1212,10 @@
248 {group} must exist at the moment this command is executed.
249
250 The {group} highlighting still applies when a character is
251- to be highlighted for 'hlsearch'.
252+ to be highlighted for 'hlsearch', as the highlighting for
253+ matches is given higher priority than that of 'hlsearch'.
254+ Syntax highlighting (see 'syntax') is also overruled by
255+ matches.
256
257 Note that highlighting the last used search pattern with
258 'hlsearch' is used in all windows, while the pattern defined
259@@ -1226,8 +1229,15 @@
260 display you may get unexpected results. That is because Vim
261 looks for a match in the line where redrawing starts.
262
263- Also see |matcharg()|, it returns the highlight group and
264- pattern of a previous :match command.
265+ Also see |matcharg()|and |getmatches()|. The former returns
266+ the highlight group and pattern of a previous |:match|
267+ command. The latter returns a list with highlight groups and
268+ patterns defined by both |matchadd()| and |:match|.
269+
270+ Highlighting matches using |:match| are limited to three
271+ matches (aside from |:match|, |:2match| and |:3match|are
272+ available). |matchadd()| does not have this limitation and in
273+ addition makes it possible to prioritize matches.
274
275 Another example, which highlights all characters in virtual
276 column 72 and more: >
277diff -Naur vim71.orig/runtime/doc/pi_paren.txt vim71/runtime/doc/pi_paren.txt
278--- vim71.orig/runtime/doc/pi_paren.txt 2007-05-12 03:18:47.000000000 -0700
279+++ vim71/runtime/doc/pi_paren.txt 2007-09-03 22:15:20.000000000 -0700
280@@ -12,8 +12,8 @@
281 You can avoid loading this plugin by setting the "loaded_matchparen" variable: >
282 :let loaded_matchparen = 1
283
284-The plugin installs CursorMoved autocommands to redefine the match
285-highlighting.
286+The plugin installs CursorMoved, CursorMovedI and WinEnter autocommands to
287+redefine the match highlighting.
288
289 To disable the plugin after it was loaded use this command: >
290
291diff -Naur vim71.orig/runtime/doc/usr_41.txt vim71/runtime/doc/usr_41.txt
292--- vim71.orig/runtime/doc/usr_41.txt 2007-05-12 03:18:48.000000000 -0700
293+++ vim71/runtime/doc/usr_41.txt 2007-09-03 22:13:43.000000000 -0700
294@@ -763,13 +763,22 @@
295 foldtextresult() get the text displayed for a closed fold
296
297 Syntax and highlighting:
298+ clearmatches() clear all matches defined by |matchadd()| and
299+ the |:match| commands
300+ getmatches() get all matches defined by |matchadd()| and
301+ the |:match| commands
302 hlexists() check if a highlight group exists
303 hlID() get ID of a highlight group
304 synID() get syntax ID at a specific position
305 synIDattr() get a specific attribute of a syntax ID
306 synIDtrans() get translated syntax ID
307 diff_hlID() get highlight ID for diff mode at a position
308+ matchadd() define a pattern to highlight (a "match")
309 matcharg() get info about |:match| arguments
310+ matchdelete() delete a match defined by |matchadd()| or a
311+ |:match| command
312+ setmatches() restore a list of matches saved by
313+ |getmatches()|
314
315 Spelling:
316 spellbadword() locate badly spelled word at or after cursor
317diff -Naur vim71.orig/runtime/doc/windows.txt vim71/runtime/doc/windows.txt
318--- vim71.orig/runtime/doc/windows.txt 2007-05-12 03:18:49.000000000 -0700
319+++ vim71/runtime/doc/windows.txt 2007-09-03 22:14:47.000000000 -0700
320@@ -132,7 +132,8 @@
321 the same file. Make new window N high (default is to use half
322 the height of the current window). Reduces the current window
323 height to create room (and others, if the 'equalalways' option
324- is set and 'eadirection' isn't "hor").
325+ is set, 'eadirection' isn't "hor", and one of them is higher
326+ than the current or the new window).
327 Note: CTRL-S does not work on all terminals and might block
328 further input, use CTRL-Q to get going again.
329 Also see |++opt| and |+cmd|.
330@@ -140,9 +141,13 @@
331 CTRL-W CTRL-V *CTRL-W_CTRL-V*
332 CTRL-W v *CTRL-W_v*
333 :[N]vs[plit] [++opt] [+cmd] [file] *:vs* *:vsplit*
334- Like |:split|, but split vertically. If 'equalalways' is set
335- and 'eadirection' isn't "ver" the windows will be spread out
336- horizontally, unless a width was specified.
337+ Like |:split|, but split vertically. The windows will be
338+ spread out horizontally if
339+ 1. a width was not specified,
340+ 2. 'equalalways' is set,
341+ 3. 'eadirection' isn't "ver", and
342+ 4. one of the other windows are wider than the current or new
343+ window.
344 Note: In other places CTRL-Q does the same as CTRL-V, but here
345 it doesn't!
346
347diff -Naur vim71.orig/runtime/filetype.vim vim71/runtime/filetype.vim
348--- vim71.orig/runtime/filetype.vim 2007-05-10 08:14:37.000000000 -0700
349+++ vim71/runtime/filetype.vim 2007-09-03 22:12:17.000000000 -0700
350@@ -1,7 +1,7 @@
351 " Vim support file to detect file types
352 "
353 " Maintainer: Bram Moolenaar <Bram@vim.org>
354-" Last Change: 2007 May 10
355+" Last Change: 2007 May 15
356
357 " Listen very carefully, I will say this only once
358 if exists("did_load_filetypes")
359@@ -1286,7 +1286,7 @@
360 au BufNewFile,BufRead *.it,*.ih setf ppwiz
361
362 " Oracle Pro*C/C++
363-au BufNewFile,BufRead .pc setf proc
364+au BufNewFile,BufRead *.pc setf proc
365
366 " Privoxy actions file
367 au BufNewFile,BufRead *.action setf privoxy
368diff -Naur vim71.orig/runtime/plugin/matchparen.vim vim71/runtime/plugin/matchparen.vim
369--- vim71.orig/runtime/plugin/matchparen.vim 2006-10-12 13:05:05.000000000 -0700
370+++ vim71/runtime/plugin/matchparen.vim 2007-09-03 22:15:20.000000000 -0700
371@@ -1,6 +1,6 @@
372 " Vim plugin for showing matching parens
373 " Maintainer: Bram Moolenaar <Bram@vim.org>
374-" Last Change: 2006 Oct 12
375+" Last Change: 2007 Aug 8
376
377 " Exit quickly when:
378 " - this plugin was already loaded (or disabled)
379@@ -13,7 +13,7 @@
380
381 augroup matchparen
382 " Replace all matchparen autocommands
383- autocmd! CursorMoved,CursorMovedI * call s:Highlight_Matching_Pair()
384+ autocmd! CursorMoved,CursorMovedI,WinEnter * call s:Highlight_Matching_Pair()
385 augroup END
386
387 " Skip the rest if it was already done.
388@@ -62,25 +62,37 @@
389 " Figure out the arguments for searchpairpos().
390 " Restrict the search to visible lines with "stopline".
391 " And avoid searching very far (e.g., for closed folds and long lines)
392+ " The "viewable" variables give a range in which we can scroll while keeping
393+ " the cursor at the same position
394+ " adjustedScrolloff accounts for very large numbers of scrolloff
395+ let adjustedScrolloff = min([&scrolloff, (line('w$') - line('w0')) / 2])
396+ let bottom_viewable = min([line('$'), c_lnum + &lines - adjustedScrolloff - 2])
397+ let top_viewable = max([1, c_lnum-&lines+adjustedScrolloff + 2])
398+ " one of these stoplines will be adjusted below, but the current values are
399+ " minimal boundaries within the current window
400+ let stoplinebottom = line('w$')
401+ let stoplinetop = line('w0')
402 if i % 2 == 0
403 let s_flags = 'nW'
404 let c2 = plist[i + 1]
405 if has("byte_offset") && has("syntax_items") && &smc > 0
406 let stopbyte = min([line2byte("$"), line2byte(".") + col(".") + &smc * 2])
407- let stopline = min([line('w$'), byte2line(stopbyte)])
408+ let stopline = min([bottom_viewable, byte2line(stopbyte)])
409 else
410- let stopline = min([line('w$'), c_lnum + 100])
411+ let stopline = min([bottom_viewable, c_lnum + 100])
412 endif
413+ let stoplinebottom = stopline
414 else
415 let s_flags = 'nbW'
416 let c2 = c
417 let c = plist[i - 1]
418 if has("byte_offset") && has("syntax_items") && &smc > 0
419 let stopbyte = max([1, line2byte(".") + col(".") - &smc * 2])
420- let stopline = max([line('w0'), byte2line(stopbyte)])
421+ let stopline = max([top_viewable, byte2line(stopbyte)])
422 else
423- let stopline = max([line('w0'), c_lnum - 100])
424+ let stopline = max([top_viewable, c_lnum - 100])
425 endif
426+ let stoplinetop = stopline
427 endif
428 if c == '['
429 let c = '\['
430@@ -106,7 +118,7 @@
431 endif
432
433 " If a match is found setup match highlighting.
434- if m_lnum > 0 && m_lnum >= line('w0') && m_lnum <= line('w$')
435+ if m_lnum > 0 && m_lnum >= stoplinetop && m_lnum <= stoplinebottom
436 exe '3match MatchParen /\(\%' . c_lnum . 'l\%' . (c_col - before) .
437 \ 'c\)\|\(\%' . m_lnum . 'l\%' . m_col . 'c\)/'
438 let w:paren_hl_on = 1
439@@ -114,7 +126,8 @@
440 endfunction
441
442 " Define commands that will disable and enable the plugin.
443-command! NoMatchParen 3match none | unlet! g:loaded_matchparen | au! matchparen
444-command! DoMatchParen runtime plugin/matchparen.vim | doau CursorMoved
445+command! NoMatchParen windo 3match none | unlet! g:loaded_matchparen |
446+ \ au! matchparen
447+command! DoMatchParen runtime plugin/matchparen.vim | windo doau CursorMoved
448
449 let &cpo = cpo_save
450diff -Naur vim71.orig/src/auto/configure vim71/src/auto/configure
451--- vim71.orig/src/auto/configure 2007-05-12 04:49:09.000000000 -0700
452+++ vim71/src/auto/configure 2007-09-03 22:12:46.000000000 -0700
453@@ -3843,7 +3843,9 @@
454 fi
455
456 if test "X$vi_cv_path_mzscheme_pfx" != "X"; then
457- if test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
458+ if test "x$MACOSX" = "xyes"; then
459+ MZSCHEME_LIBS="-framework PLT_MzScheme"
460+ elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
461 MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme.a ${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"
462 else
463 MZSCHEME_LIBS="-L${vi_cv_path_mzscheme_pfx}/lib -lmzscheme -lmzgc"
464diff -Naur vim71.orig/src/buffer.c vim71/src/buffer.c
465--- vim71.orig/src/buffer.c 2007-05-10 08:25:59.000000000 -0700
466+++ vim71/src/buffer.c 2007-09-03 22:14:43.000000000 -0700
467@@ -171,6 +171,13 @@
468 /* Put the cursor on the first line. */
469 curwin->w_cursor.lnum = 1;
470 curwin->w_cursor.col = 0;
471+
472+ /* Set or reset 'modified' before executing autocommands, so that
473+ * it can be changed there. */
474+ if (!readonlymode && !bufempty())
475+ changed();
476+ else if (retval != FAIL)
477+ unchanged(curbuf, FALSE);
478 #ifdef FEAT_AUTOCMD
479 # ifdef FEAT_EVAL
480 apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, FALSE,
481@@ -194,16 +201,16 @@
482 /* When reading stdin, the buffer contents always needs writing, so set
483 * the changed flag. Unless in readonly mode: "ls | gview -".
484 * When interrupted and 'cpoptions' contains 'i' set changed flag. */
485- if ((read_stdin && !readonlymode && !bufempty())
486+ if ((got_int && vim_strchr(p_cpo, CPO_INTMOD) != NULL)
487 #ifdef FEAT_AUTOCMD
488 || modified_was_set /* ":set modified" used in autocmd */
489 # ifdef FEAT_EVAL
490 || (aborting() && vim_strchr(p_cpo, CPO_INTMOD) != NULL)
491 # endif
492 #endif
493- || (got_int && vim_strchr(p_cpo, CPO_INTMOD) != NULL))
494+ )
495 changed();
496- else if (retval != FAIL)
497+ else if (retval != FAIL && !read_stdin)
498 unchanged(curbuf, FALSE);
499 save_file_ff(curbuf); /* keep this fileformat */
500
501@@ -495,6 +502,7 @@
502 buf->b_start_eol = TRUE;
503 #ifdef FEAT_MBYTE
504 buf->b_p_bomb = FALSE;
505+ buf->b_start_bomb = FALSE;
506 #endif
507 buf->b_ml.ml_mfp = NULL;
508 buf->b_ml.ml_flags = ML_EMPTY; /* empty buffer */
509@@ -4853,7 +4861,7 @@
510 */
511 for (e = s; *e != ':' && *e != NUL; ++e)
512 if (e[0] == '\\' && e[1] == ':')
513- STRCPY(e, e + 1);
514+ mch_memmove(e, e + 1, STRLEN(e));
515 if (*e == NUL)
516 end = TRUE;
517
518diff -Naur vim71.orig/src/charset.c vim71/src/charset.c
519--- vim71.orig/src/charset.c 2007-03-24 13:10:37.000000000 -0700
520+++ vim71/src/charset.c 2007-09-03 22:15:22.000000000 -0700
521@@ -207,7 +207,10 @@
522 }
523 while (c <= c2)
524 {
525- if (!do_isalpha || isalpha(c)
526+ /* Use the MB_ functions here, because isalpha() doesn't
527+ * work properly when 'encoding' is "latin1" and the locale is
528+ * "C". */
529+ if (!do_isalpha || MB_ISLOWER(c) || MB_ISUPPER(c)
530 #ifdef FEAT_FKMAP
531 || (p_altkeymap && (F_isalpha(c) || F_isdigit(c)))
532 #endif
533@@ -929,6 +932,23 @@
534 }
535
536 /*
537+ * return TRUE if 'c' is a valid file-name character or a wildcard character
538+ * Assume characters above 0x100 are valid (multi-byte).
539+ * Explicitly interpret ']' as a wildcard character as mch_has_wildcard("]")
540+ * returns false.
541+ */
542+ int
543+vim_isfilec_or_wc(c)
544+ int c;
545+{
546+ char_u buf[2];
547+
548+ buf[0] = (char_u)c;
549+ buf[1] = NUL;
550+ return vim_isfilec(c) || c == ']' || mch_has_wildcard(buf);
551+}
552+
553+/*
554 * return TRUE if 'c' is a printable character
555 * Assume characters above 0x100 are printable (multi-byte), except for
556 * Unicode.
557@@ -1898,7 +1918,7 @@
558 {
559 for ( ; *p; ++p)
560 if (rem_backslash(p))
561- STRCPY(p, p + 1);
562+ mch_memmove(p, p + 1, STRLEN(p));
563 }
564
565 /*
566diff -Naur vim71.orig/src/configure.in vim71/src/configure.in
567--- vim71.orig/src/configure.in 2007-05-12 02:19:27.000000000 -0700
568+++ vim71/src/configure.in 2007-09-03 22:12:46.000000000 -0700
569@@ -423,7 +423,9 @@
570 fi
571
572 if test "X$vi_cv_path_mzscheme_pfx" != "X"; then
573- if test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
574+ if test "x$MACOSX" = "xyes"; then
575+ MZSCHEME_LIBS="-framework PLT_MzScheme"
576+ elif test -f "${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"; then
577 MZSCHEME_LIBS="${vi_cv_path_mzscheme_pfx}/lib/libmzscheme.a ${vi_cv_path_mzscheme_pfx}/lib/libmzgc.a"
578 else
579 MZSCHEME_LIBS="-L${vi_cv_path_mzscheme_pfx}/lib -lmzscheme -lmzgc"
580diff -Naur vim71.orig/src/digraph.c vim71/src/digraph.c
581--- vim71.orig/src/digraph.c 2006-05-02 11:24:04.000000000 -0700
582+++ vim71/src/digraph.c 2007-09-03 22:13:01.000000000 -0700
583@@ -2349,8 +2349,10 @@
584
585 if (*curbuf->b_p_keymap == NUL)
586 {
587- /* Stop any active keymap and clear the table. */
588+ /* Stop any active keymap and clear the table. Also remove
589+ * b:keymap_unload, as no keymap is active now. */
590 keymap_unload();
591+ do_cmdline_cmd((char_u *)"unlet! b:keymap_name");
592 }
593 else
594 {
595@@ -2500,7 +2502,6 @@
596
597 ga_clear(&curbuf->b_kmap_ga);
598 curbuf->b_kmap_state &= ~KEYMAP_LOADED;
599- do_cmdline_cmd((char_u *)"unlet! b:keymap_name");
600 #ifdef FEAT_WINDOWS
601 status_redraw_curbuf();
602 #endif
603diff -Naur vim71.orig/src/edit.c vim71/src/edit.c
604--- vim71.orig/src/edit.c 2007-05-07 12:43:55.000000000 -0700
605+++ vim71/src/edit.c 2007-09-03 22:14:45.000000000 -0700
606@@ -2057,7 +2057,6 @@
607 * case of the originally typed text is used, and the case of the completed
608 * text is inferred, ie this tries to work out what case you probably wanted
609 * the rest of the word to be in -- webb
610- * TODO: make this work for multi-byte characters.
611 */
612 int
613 ins_compl_add_infercase(str, len, icase, fname, dir, flags)
614@@ -2068,54 +2067,147 @@
615 int dir;
616 int flags;
617 {
618+ char_u *p;
619+ int i, c;
620+ int actual_len; /* Take multi-byte characters */
621+ int actual_compl_length; /* into account. */
622+ int *wca; /* Wide character array. */
623 int has_lower = FALSE;
624 int was_letter = FALSE;
625- int idx;
626
627- if (p_ic && curbuf->b_p_inf && len < IOSIZE)
628+ if (p_ic && curbuf->b_p_inf)
629 {
630- /* Infer case of completed part -- webb */
631- /* Use IObuff, str would change text in buffer! */
632- vim_strncpy(IObuff, str, len);
633+ /* Infer case of completed part. */
634
635- /* Rule 1: Were any chars converted to lower? */
636- for (idx = 0; idx < compl_length; ++idx)
637+ /* Find actual length of completion. */
638+#ifdef FEAT_MBYTE
639+ if (has_mbyte)
640 {
641- if (islower(compl_orig_text[idx]))
642+ p = str;
643+ actual_len = 0;
644+ while (*p != NUL)
645 {
646- has_lower = TRUE;
647- if (isupper(IObuff[idx]))
648- {
649- /* Rule 1 is satisfied */
650- for (idx = compl_length; idx < len; ++idx)
651- IObuff[idx] = TOLOWER_LOC(IObuff[idx]);
652- break;
653- }
654+ mb_ptr_adv(p);
655+ ++actual_len;
656 }
657 }
658+ else
659+#endif
660+ actual_len = len;
661
662- /*
663- * Rule 2: No lower case, 2nd consecutive letter converted to
664- * upper case.
665- */
666- if (!has_lower)
667+ /* Find actual length of original text. */
668+#ifdef FEAT_MBYTE
669+ if (has_mbyte)
670+ {
671+ p = compl_orig_text;
672+ actual_compl_length = 0;
673+ while (*p != NUL)
674+ {
675+ mb_ptr_adv(p);
676+ ++actual_compl_length;
677+ }
678+ }
679+ else
680+#endif
681+ actual_compl_length = compl_length;
682+
683+ /* Allocate wide character array for the completion and fill it. */
684+ wca = (int *)alloc(actual_len * sizeof(int));
685+ if (wca != NULL)
686 {
687- for (idx = 0; idx < compl_length; ++idx)
688+ p = str;
689+ for (i = 0; i < actual_len; ++i)
690+#ifdef FEAT_MBYTE
691+ if (has_mbyte)
692+ wca[i] = mb_ptr2char_adv(&p);
693+ else
694+#endif
695+ wca[i] = *(p++);
696+
697+ /* Rule 1: Were any chars converted to lower? */
698+ p = compl_orig_text;
699+ for (i = 0; i < actual_compl_length; ++i)
700 {
701- if (was_letter && isupper(compl_orig_text[idx])
702- && islower(IObuff[idx]))
703+#ifdef FEAT_MBYTE
704+ if (has_mbyte)
705+ c = mb_ptr2char_adv(&p);
706+ else
707+#endif
708+ c = *(p++);
709+ if (MB_ISLOWER(c))
710 {
711- /* Rule 2 is satisfied */
712- for (idx = compl_length; idx < len; ++idx)
713- IObuff[idx] = TOUPPER_LOC(IObuff[idx]);
714- break;
715+ has_lower = TRUE;
716+ if (MB_ISUPPER(wca[i]))
717+ {
718+ /* Rule 1 is satisfied. */
719+ for (i = actual_compl_length; i < actual_len; ++i)
720+ wca[i] = MB_TOLOWER(wca[i]);
721+ break;
722+ }
723 }
724- was_letter = isalpha(compl_orig_text[idx]);
725 }
726- }
727
728- /* Copy the original case of the part we typed */
729- STRNCPY(IObuff, compl_orig_text, compl_length);
730+ /*
731+ * Rule 2: No lower case, 2nd consecutive letter converted to
732+ * upper case.
733+ */
734+ if (!has_lower)
735+ {
736+ p = compl_orig_text;
737+ for (i = 0; i < actual_compl_length; ++i)
738+ {
739+#ifdef FEAT_MBYTE
740+ if (has_mbyte)
741+ c = mb_ptr2char_adv(&p);
742+ else
743+#endif
744+ c = *(p++);
745+ if (was_letter && MB_ISUPPER(c) && MB_ISLOWER(wca[i]))
746+ {
747+ /* Rule 2 is satisfied. */
748+ for (i = actual_compl_length; i < actual_len; ++i)
749+ wca[i] = MB_TOUPPER(wca[i]);
750+ break;
751+ }
752+ was_letter = MB_ISLOWER(c) || MB_ISUPPER(c);
753+ }
754+ }
755+
756+ /* Copy the original case of the part we typed. */
757+ p = compl_orig_text;
758+ for (i = 0; i < actual_compl_length; ++i)
759+ {
760+#ifdef FEAT_MBYTE
761+ if (has_mbyte)
762+ c = mb_ptr2char_adv(&p);
763+ else
764+#endif
765+ c = *(p++);
766+ if (MB_ISLOWER(c))
767+ wca[i] = MB_TOLOWER(wca[i]);
768+ else if (MB_ISUPPER(c))
769+ wca[i] = MB_TOUPPER(wca[i]);
770+ }
771+
772+ /*
773+ * Generate encoding specific output from wide character array.
774+ * Multi-byte characters can occupy up to five bytes more than
775+ * ASCII characters, and we also need one byte for NUL, so stay
776+ * six bytes away from the edge of IObuff.
777+ */
778+ p = IObuff;
779+ i = 0;
780+ while (i < actual_len && (p - IObuff + 6) < IOSIZE)
781+#ifdef FEAT_MBYTE
782+ if (has_mbyte)
783+ p += mb_char2bytes(wca[i++], p);
784+ else
785+#endif
786+ *(p++) = wca[i++];
787+ *p = NUL;
788+
789+ vim_free(wca);
790+ }
791
792 return ins_compl_add(IObuff, len, icase, fname, NULL, dir,
793 flags, FALSE);
794@@ -2842,6 +2934,7 @@
795 /*
796 * Add the other matches on the line
797 */
798+ ptr = buf;
799 while (!got_int)
800 {
801 /* Find start of the next word. Skip white
802@@ -2851,7 +2944,7 @@
803 break;
804 wstart = ptr;
805
806- /* Find end of the word and add it. */
807+ /* Find end of the word. */
808 #ifdef FEAT_MBYTE
809 if (has_mbyte)
810 /* Japanese words may have characters in
811@@ -2868,9 +2961,12 @@
812 else
813 #endif
814 ptr = find_word_end(ptr);
815- add_r = ins_compl_add_infercase(wstart,
816- (int)(ptr - wstart),
817- p_ic, files[i], *dir, 0);
818+
819+ /* Add the word. Skip the regexp match. */
820+ if (wstart != regmatch->startp[0])
821+ add_r = ins_compl_add_infercase(wstart,
822+ (int)(ptr - wstart),
823+ p_ic, files[i], *dir, 0);
824 }
825 }
826 if (add_r == OK)
827@@ -7215,6 +7311,8 @@
828 p = ml_get_curline();
829 if (cin_iscase(p) || cin_isscopedecl(p) || cin_islabel(30))
830 return TRUE;
831+ /* Need to get the line again after cin_islabel(). */
832+ p = ml_get_curline();
833 if (curwin->w_cursor.col > 2
834 && p[curwin->w_cursor.col - 1] == ':'
835 && p[curwin->w_cursor.col - 2] == ':')
836@@ -7998,7 +8096,8 @@
837 /*
838 * 0^D and ^^D: remove all indent.
839 */
840- if ((lastc == '0' || lastc == '^') && curwin->w_cursor.col)
841+ if (c == Ctrl_D && (lastc == '0' || lastc == '^')
842+ && curwin->w_cursor.col > 0)
843 {
844 --curwin->w_cursor.col;
845 (void)del_char(FALSE); /* delete the '^' or '0' */
846diff -Naur vim71.orig/src/eval.c vim71/src/eval.c
847--- vim71.orig/src/eval.c 2007-05-07 12:47:32.000000000 -0700
848+++ vim71/src/eval.c 2007-09-03 22:15:36.000000000 -0700
849@@ -369,17 +369,17 @@
850 static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars));
851 static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon));
852 static char_u *skip_var_one __ARGS((char_u *arg));
853-static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty));
854-static void list_glob_vars __ARGS((void));
855-static void list_buf_vars __ARGS((void));
856-static void list_win_vars __ARGS((void));
857+static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty, int *first));
858+static void list_glob_vars __ARGS((int *first));
859+static void list_buf_vars __ARGS((int *first));
860+static void list_win_vars __ARGS((int *first));
861 #ifdef FEAT_WINDOWS
862-static void list_tab_vars __ARGS((void));
863+static void list_tab_vars __ARGS((int *first));
864 #endif
865-static void list_vim_vars __ARGS((void));
866-static void list_script_vars __ARGS((void));
867-static void list_func_vars __ARGS((void));
868-static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg));
869+static void list_vim_vars __ARGS((int *first));
870+static void list_script_vars __ARGS((int *first));
871+static void list_func_vars __ARGS((int *first));
872+static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg, int *first));
873 static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op));
874 static int check_changedtick __ARGS((char_u *arg));
875 static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet, int fne_flags));
876@@ -475,6 +475,7 @@
877 static void f_changenr __ARGS((typval_T *argvars, typval_T *rettv));
878 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv));
879 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv));
880+static void f_clearmatches __ARGS((typval_T *argvars, typval_T *rettv));
881 static void f_col __ARGS((typval_T *argvars, typval_T *rettv));
882 #if defined(FEAT_INS_EXPAND)
883 static void f_complete __ARGS((typval_T *argvars, typval_T *rettv));
884@@ -529,6 +530,7 @@
885 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv));
886 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv));
887 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv));
888+static void f_getmatches __ARGS((typval_T *argvars, typval_T *rettv));
889 static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv));
890 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv));
891 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv));
892@@ -577,7 +579,9 @@
893 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv));
894 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv));
895 static void f_match __ARGS((typval_T *argvars, typval_T *rettv));
896+static void f_matchadd __ARGS((typval_T *argvars, typval_T *rettv));
897 static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv));
898+static void f_matchdelete __ARGS((typval_T *argvars, typval_T *rettv));
899 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv));
900 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv));
901 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv));
902@@ -618,6 +622,7 @@
903 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv));
904 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv));
905 static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv));
906+static void f_setmatches __ARGS((typval_T *argvars, typval_T *rettv));
907 static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv));
908 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv));
909 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv));
910@@ -672,7 +677,7 @@
911 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv));
912
913 static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump));
914-static pos_T *var2fpos __ARGS((typval_T *varp, int lnum, int *fnum));
915+static pos_T *var2fpos __ARGS((typval_T *varp, int dollar_lnum, int *fnum));
916 static int get_env_len __ARGS((char_u **arg));
917 static int get_id_len __ARGS((char_u **arg));
918 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose));
919@@ -699,8 +704,8 @@
920 static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname));
921 static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val));
922 static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi));
923-static void list_one_var __ARGS((dictitem_T *v, char_u *prefix));
924-static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string));
925+static void list_one_var __ARGS((dictitem_T *v, char_u *prefix, int *first));
926+static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string, int *first));
927 static void set_var __ARGS((char_u *name, typval_T *varp, int copy));
928 static int var_check_ro __ARGS((int flags, char_u *name));
929 static int var_check_fixed __ARGS((int flags, char_u *name));
930@@ -992,20 +997,20 @@
931 char_u *value;
932 int value_len;
933 {
934- size_t len;
935+ int len;
936
937 if (redir_lval == NULL)
938 return;
939
940 if (value_len == -1)
941- len = STRLEN(value); /* Append the entire string */
942+ len = (int)STRLEN(value); /* Append the entire string */
943 else
944- len = value_len; /* Append only "value_len" characters */
945+ len = value_len; /* Append only "value_len" characters */
946
947- if (ga_grow(&redir_ga, (int)len) == OK)
948+ if (ga_grow(&redir_ga, len) == OK)
949 {
950 mch_memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len);
951- redir_ga.ga_len += (int)len;
952+ redir_ga.ga_len += len;
953 }
954 else
955 var_redir_stop();
956@@ -1411,7 +1416,8 @@
957 }
958
959
960-#if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO)
961+#if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) \
962+ || defined(FEAT_COMPL_FUNC) || defined(PROTO)
963 /*
964 * Call some vimL function and return the result in "*rettv".
965 * Uses argv[argc] for the function arguments.
966@@ -1484,6 +1490,7 @@
967 return ret;
968 }
969
970+# if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO)
971 /*
972 * Call vimL function "func" and return the result as a string.
973 * Returns NULL when calling the function fails.
974@@ -1506,8 +1513,9 @@
975 clear_tv(&rettv);
976 return retval;
977 }
978+# endif
979
980-#if defined(FEAT_COMPL_FUNC) || defined(PROTO)
981+# if defined(FEAT_COMPL_FUNC) || defined(PROTO)
982 /*
983 * Call vimL function "func" and return the result as a number.
984 * Returns -1 when calling the function fails.
985@@ -1530,7 +1538,7 @@
986 clear_tv(&rettv);
987 return retval;
988 }
989-#endif
990+# endif
991
992 /*
993 * Call vimL function "func" and return the result as a list
994@@ -1556,9 +1564,9 @@
995
996 return rettv.vval.v_list;
997 }
998-
999 #endif
1000
1001+
1002 /*
1003 * Save the current function call pointer, and set it to NULL.
1004 * Used when executing autocommands and for ":source".
1005@@ -1691,6 +1699,7 @@
1006 int semicolon = 0;
1007 char_u op[2];
1008 char_u *argend;
1009+ int first = TRUE;
1010
1011 argend = skip_var_list(arg, &var_count, &semicolon);
1012 if (argend == NULL)
1013@@ -1707,19 +1716,19 @@
1014 EMSG(_(e_invarg));
1015 else if (!ends_excmd(*arg))
1016 /* ":let var1 var2" */
1017- arg = list_arg_vars(eap, arg);
1018+ arg = list_arg_vars(eap, arg, &first);
1019 else if (!eap->skip)
1020 {
1021 /* ":let" */
1022- list_glob_vars();
1023- list_buf_vars();
1024- list_win_vars();
1025+ list_glob_vars(&first);
1026+ list_buf_vars(&first);
1027+ list_win_vars(&first);
1028 #ifdef FEAT_WINDOWS
1029- list_tab_vars();
1030+ list_tab_vars(&first);
1031 #endif
1032- list_script_vars();
1033- list_func_vars();
1034- list_vim_vars();
1035+ list_script_vars(&first);
1036+ list_func_vars(&first);
1037+ list_vim_vars(&first);
1038 }
1039 eap->nextcmd = check_nextcmd(arg);
1040 }
1041@@ -1924,10 +1933,11 @@
1042 * If "empty" is TRUE also list NULL strings as empty strings.
1043 */
1044 static void
1045-list_hashtable_vars(ht, prefix, empty)
1046+list_hashtable_vars(ht, prefix, empty, first)
1047 hashtab_T *ht;
1048 char_u *prefix;
1049 int empty;
1050+ int *first;
1051 {
1052 hashitem_T *hi;
1053 dictitem_T *di;
1054@@ -1942,7 +1952,7 @@
1055 di = HI2DI(hi);
1056 if (empty || di->di_tv.v_type != VAR_STRING
1057 || di->di_tv.vval.v_string != NULL)
1058- list_one_var(di, prefix);
1059+ list_one_var(di, prefix, first);
1060 }
1061 }
1062 }
1063@@ -1951,32 +1961,38 @@
1064 * List global variables.
1065 */
1066 static void
1067-list_glob_vars()
1068+list_glob_vars(first)
1069+ int *first;
1070 {
1071- list_hashtable_vars(&globvarht, (char_u *)"", TRUE);
1072+ list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first);
1073 }
1074
1075 /*
1076 * List buffer variables.
1077 */
1078 static void
1079-list_buf_vars()
1080+list_buf_vars(first)
1081+ int *first;
1082 {
1083 char_u numbuf[NUMBUFLEN];
1084
1085- list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE);
1086+ list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:",
1087+ TRUE, first);
1088
1089 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick);
1090- list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf);
1091+ list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER,
1092+ numbuf, first);
1093 }
1094
1095 /*
1096 * List window variables.
1097 */
1098 static void
1099-list_win_vars()
1100+list_win_vars(first)
1101+ int *first;
1102 {
1103- list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE);
1104+ list_hashtable_vars(&curwin->w_vars.dv_hashtab,
1105+ (char_u *)"w:", TRUE, first);
1106 }
1107
1108 #ifdef FEAT_WINDOWS
1109@@ -1984,9 +2000,11 @@
1110 * List tab page variables.
1111 */
1112 static void
1113-list_tab_vars()
1114+list_tab_vars(first)
1115+ int *first;
1116 {
1117- list_hashtable_vars(&curtab->tp_vars.dv_hashtab, (char_u *)"t:", TRUE);
1118+ list_hashtable_vars(&curtab->tp_vars.dv_hashtab,
1119+ (char_u *)"t:", TRUE, first);
1120 }
1121 #endif
1122
1123@@ -1994,39 +2012,44 @@
1124 * List Vim variables.
1125 */
1126 static void
1127-list_vim_vars()
1128+list_vim_vars(first)
1129+ int *first;
1130 {
1131- list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE);
1132+ list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first);
1133 }
1134
1135 /*
1136 * List script-local variables, if there is a script.
1137 */
1138 static void
1139-list_script_vars()
1140+list_script_vars(first)
1141+ int *first;
1142 {
1143 if (current_SID > 0 && current_SID <= ga_scripts.ga_len)
1144- list_hashtable_vars(&SCRIPT_VARS(current_SID), (char_u *)"s:", FALSE);
1145+ list_hashtable_vars(&SCRIPT_VARS(current_SID),
1146+ (char_u *)"s:", FALSE, first);
1147 }
1148
1149 /*
1150 * List function variables, if there is a function.
1151 */
1152 static void
1153-list_func_vars()
1154+list_func_vars(first)
1155+ int *first;
1156 {
1157 if (current_funccal != NULL)
1158 list_hashtable_vars(&current_funccal->l_vars.dv_hashtab,
1159- (char_u *)"l:", FALSE);
1160+ (char_u *)"l:", FALSE, first);
1161 }
1162
1163 /*
1164 * List variables in "arg".
1165 */
1166 static char_u *
1167-list_arg_vars(eap, arg)
1168+list_arg_vars(eap, arg, first)
1169 exarg_T *eap;
1170 char_u *arg;
1171+ int *first;
1172 {
1173 int error = FALSE;
1174 int len;
1175@@ -2083,15 +2106,15 @@
1176 {
1177 switch (*name)
1178 {
1179- case 'g': list_glob_vars(); break;
1180- case 'b': list_buf_vars(); break;
1181- case 'w': list_win_vars(); break;
1182+ case 'g': list_glob_vars(first); break;
1183+ case 'b': list_buf_vars(first); break;
1184+ case 'w': list_win_vars(first); break;
1185 #ifdef FEAT_WINDOWS
1186- case 't': list_tab_vars(); break;
1187+ case 't': list_tab_vars(first); break;
1188 #endif
1189- case 'v': list_vim_vars(); break;
1190- case 's': list_script_vars(); break;
1191- case 'l': list_func_vars(); break;
1192+ case 'v': list_vim_vars(first); break;
1193+ case 's': list_script_vars(first); break;
1194+ case 'l': list_func_vars(first); break;
1195 default:
1196 EMSG2(_("E738: Can't list variables for %s"), name);
1197 }
1198@@ -2108,7 +2131,9 @@
1199 *arg = NUL;
1200 list_one_var_a((char_u *)"",
1201 arg == arg_subsc ? name : name_start,
1202- tv.v_type, s == NULL ? (char_u *)"" : s);
1203+ tv.v_type,
1204+ s == NULL ? (char_u *)"" : s,
1205+ first);
1206 *arg = c;
1207 vim_free(tf);
1208 }
1209@@ -6794,7 +6819,7 @@
1210 * "numbuf" is used for a number.
1211 * Does not put quotes around strings, as ":echo" displays values.
1212 * When "copyID" is not NULL replace recursive lists and dicts with "...".
1213- * May return NULL;
1214+ * May return NULL.
1215 */
1216 static char_u *
1217 echo_string(tv, tofree, numbuf, copyID)
1218@@ -6879,7 +6904,7 @@
1219 * If the memory is allocated "tofree" is set to it, otherwise NULL.
1220 * "numbuf" is used for a number.
1221 * Puts quotes around strings, so that they can be parsed back by eval().
1222- * May return NULL;
1223+ * May return NULL.
1224 */
1225 static char_u *
1226 tv2string(tv, tofree, numbuf, copyID)
1227@@ -7043,6 +7068,7 @@
1228 {"changenr", 0, 0, f_changenr},
1229 {"char2nr", 1, 1, f_char2nr},
1230 {"cindent", 1, 1, f_cindent},
1231+ {"clearmatches", 0, 0, f_clearmatches},
1232 {"col", 1, 1, f_col},
1233 #if defined(FEAT_INS_EXPAND)
1234 {"complete", 2, 2, f_complete},
1235@@ -7099,6 +7125,7 @@
1236 {"getftype", 1, 1, f_getftype},
1237 {"getline", 1, 2, f_getline},
1238 {"getloclist", 1, 1, f_getqflist},
1239+ {"getmatches", 0, 0, f_getmatches},
1240 {"getpos", 1, 1, f_getpos},
1241 {"getqflist", 0, 0, f_getqflist},
1242 {"getreg", 0, 2, f_getreg},
1243@@ -7149,7 +7176,9 @@
1244 {"maparg", 1, 3, f_maparg},
1245 {"mapcheck", 1, 3, f_mapcheck},
1246 {"match", 2, 4, f_match},
1247+ {"matchadd", 2, 4, f_matchadd},
1248 {"matcharg", 1, 1, f_matcharg},
1249+ {"matchdelete", 1, 1, f_matchdelete},
1250 {"matchend", 2, 4, f_matchend},
1251 {"matchlist", 2, 4, f_matchlist},
1252 {"matchstr", 2, 4, f_matchstr},
1253@@ -7190,6 +7219,7 @@
1254 {"setcmdpos", 1, 1, f_setcmdpos},
1255 {"setline", 2, 2, f_setline},
1256 {"setloclist", 2, 3, f_setloclist},
1257+ {"setmatches", 1, 1, f_setmatches},
1258 {"setpos", 2, 2, f_setpos},
1259 {"setqflist", 1, 2, f_setqflist},
1260 {"setreg", 2, 3, f_setreg},
1261@@ -8240,6 +8270,20 @@
1262 }
1263
1264 /*
1265+ * "clearmatches()" function
1266+ */
1267+/*ARGSUSED*/
1268+ static void
1269+f_clearmatches(argvars, rettv)
1270+ typval_T *argvars;
1271+ typval_T *rettv;
1272+{
1273+#ifdef FEAT_SEARCH_EXTRA
1274+ clear_matches(curwin);
1275+#endif
1276+}
1277+
1278+/*
1279 * "col(string)" function
1280 */
1281 static void
1282@@ -10136,7 +10180,13 @@
1283 if (mch_isdir(fname))
1284 rettv->vval.v_number = 0;
1285 else
1286+ {
1287 rettv->vval.v_number = (varnumber_T)st.st_size;
1288+
1289+ /* non-perfect check for overflow */
1290+ if ((off_t)rettv->vval.v_number != (off_t)st.st_size)
1291+ rettv->vval.v_number = -2;
1292+ }
1293 }
1294 else
1295 rettv->vval.v_number = -1;
1296@@ -10269,6 +10319,40 @@
1297 }
1298
1299 /*
1300+ * "getmatches()" function
1301+ */
1302+/*ARGSUSED*/
1303+ static void
1304+f_getmatches(argvars, rettv)
1305+ typval_T *argvars;
1306+ typval_T *rettv;
1307+{
1308+#ifdef FEAT_SEARCH_EXTRA
1309+ dict_T *dict;
1310+ matchitem_T *cur = curwin->w_match_head;
1311+
1312+ rettv->vval.v_number = 0;
1313+
1314+ if (rettv_list_alloc(rettv) == OK)
1315+ {
1316+ while (cur != NULL)
1317+ {
1318+ dict = dict_alloc();
1319+ if (dict == NULL)
1320+ return;
1321+ ++dict->dv_refcount;
1322+ dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id));
1323+ dict_add_nr_str(dict, "pattern", 0L, cur->pattern);
1324+ dict_add_nr_str(dict, "priority", (long)cur->priority, NULL);
1325+ dict_add_nr_str(dict, "id", (long)cur->id, NULL);
1326+ list_append_dict(rettv->vval.v_list, dict);
1327+ cur = cur->next;
1328+ }
1329+ }
1330+#endif
1331+}
1332+
1333+/*
1334 * "getpos(string)" function
1335 */
1336 static void
1337@@ -12439,6 +12523,44 @@
1338 }
1339
1340 /*
1341+ * "matchadd()" function
1342+ */
1343+ static void
1344+f_matchadd(argvars, rettv)
1345+ typval_T *argvars;
1346+ typval_T *rettv;
1347+{
1348+#ifdef FEAT_SEARCH_EXTRA
1349+ char_u buf[NUMBUFLEN];
1350+ char_u *grp = get_tv_string_buf_chk(&argvars[0], buf); /* group */
1351+ char_u *pat = get_tv_string_buf_chk(&argvars[1], buf); /* pattern */
1352+ int prio = 10; /* default priority */
1353+ int id = -1;
1354+ int error = FALSE;
1355+
1356+ rettv->vval.v_number = -1;
1357+
1358+ if (grp == NULL || pat == NULL)
1359+ return;
1360+ if (argvars[2].v_type != VAR_UNKNOWN)
1361+ {
1362+ prio = get_tv_number_chk(&argvars[2], &error);
1363+ if (argvars[3].v_type != VAR_UNKNOWN)
1364+ id = get_tv_number_chk(&argvars[3], &error);
1365+ }
1366+ if (error == TRUE)
1367+ return;
1368+ if (id >= 1 && id <= 3)
1369+ {
1370+ EMSGN("E798: ID is reserved for \":match\": %ld", id);
1371+ return;
1372+ }
1373+
1374+ rettv->vval.v_number = match_add(curwin, grp, pat, prio, id);
1375+#endif
1376+}
1377+
1378+/*
1379 * "matcharg()" function
1380 */
1381 static void
1382@@ -12449,20 +12571,42 @@
1383 if (rettv_list_alloc(rettv) == OK)
1384 {
1385 #ifdef FEAT_SEARCH_EXTRA
1386- int mi = get_tv_number(&argvars[0]);
1387+ int id = get_tv_number(&argvars[0]);
1388+ matchitem_T *m;
1389
1390- if (mi >= 1 && mi <= 3)
1391+ if (id >= 1 && id <= 3)
1392 {
1393- list_append_string(rettv->vval.v_list,
1394- syn_id2name(curwin->w_match_id[mi - 1]), -1);
1395- list_append_string(rettv->vval.v_list,
1396- curwin->w_match_pat[mi - 1], -1);
1397+ if ((m = (matchitem_T *)get_match(curwin, id)) != NULL)
1398+ {
1399+ list_append_string(rettv->vval.v_list,
1400+ syn_id2name(m->hlg_id), -1);
1401+ list_append_string(rettv->vval.v_list, m->pattern, -1);
1402+ }
1403+ else
1404+ {
1405+ list_append_string(rettv->vval.v_list, NUL, -1);
1406+ list_append_string(rettv->vval.v_list, NUL, -1);
1407+ }
1408 }
1409 #endif
1410 }
1411 }
1412
1413 /*
1414+ * "matchdelete()" function
1415+ */
1416+ static void
1417+f_matchdelete(argvars, rettv)
1418+ typval_T *argvars;
1419+ typval_T *rettv;
1420+{
1421+#ifdef FEAT_SEARCH_EXTRA
1422+ rettv->vval.v_number = match_delete(curwin,
1423+ (int)get_tv_number(&argvars[0]), TRUE);
1424+#endif
1425+}
1426+
1427+/*
1428 * "matchend()" function
1429 */
1430 static void
1431@@ -13680,7 +13824,7 @@
1432 }
1433 /* Shorten "remain". */
1434 if (*q != NUL)
1435- STRCPY(remain, q - 1);
1436+ mch_memmove(remain, q - 1, STRLEN(q - 1) + 1);
1437 else
1438 {
1439 vim_free(remain);
1440@@ -13919,6 +14063,8 @@
1441 /* If 'n' flag is used: restore cursor position. */
1442 if (flags & SP_NOMOVE)
1443 curwin->w_cursor = save_cursor;
1444+ else
1445+ curwin->w_set_curswant = TRUE;
1446 theend:
1447 p_ws = save_p_ws;
1448
1449@@ -14498,6 +14644,66 @@
1450 }
1451
1452 /*
1453+ * "setmatches()" function
1454+ */
1455+ static void
1456+f_setmatches(argvars, rettv)
1457+ typval_T *argvars;
1458+ typval_T *rettv;
1459+{
1460+#ifdef FEAT_SEARCH_EXTRA
1461+ list_T *l;
1462+ listitem_T *li;
1463+ dict_T *d;
1464+
1465+ rettv->vval.v_number = -1;
1466+ if (argvars[0].v_type != VAR_LIST)
1467+ {
1468+ EMSG(_(e_listreq));
1469+ return;
1470+ }
1471+ if ((l = argvars[0].vval.v_list) != NULL)
1472+ {
1473+
1474+ /* To some extent make sure that we are dealing with a list from
1475+ * "getmatches()". */
1476+ li = l->lv_first;
1477+ while (li != NULL)
1478+ {
1479+ if (li->li_tv.v_type != VAR_DICT
1480+ || (d = li->li_tv.vval.v_dict) == NULL)
1481+ {
1482+ EMSG(_(e_invarg));
1483+ return;
1484+ }
1485+ if (!(dict_find(d, (char_u *)"group", -1) != NULL
1486+ && dict_find(d, (char_u *)"pattern", -1) != NULL
1487+ && dict_find(d, (char_u *)"priority", -1) != NULL
1488+ && dict_find(d, (char_u *)"id", -1) != NULL))
1489+ {
1490+ EMSG(_(e_invarg));
1491+ return;
1492+ }
1493+ li = li->li_next;
1494+ }
1495+
1496+ clear_matches(curwin);
1497+ li = l->lv_first;
1498+ while (li != NULL)
1499+ {
1500+ d = li->li_tv.vval.v_dict;
1501+ match_add(curwin, get_dict_string(d, (char_u *)"group", FALSE),
1502+ get_dict_string(d, (char_u *)"pattern", FALSE),
1503+ (int)get_dict_number(d, (char_u *)"priority"),
1504+ (int)get_dict_number(d, (char_u *)"id"));
1505+ li = li->li_next;
1506+ }
1507+ rettv->vval.v_number = 0;
1508+ }
1509+#endif
1510+}
1511+
1512+/*
1513 * "setpos()" function
1514 */
1515 /*ARGSUSED*/
1516@@ -14785,6 +14991,10 @@
1517
1518 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1, 0);
1519 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2, 0);
1520+ if (p1 == NULL)
1521+ p1 = (char_u *)"";
1522+ if (p2 == NULL)
1523+ p2 = (char_u *)"";
1524 if (item_compare_ic)
1525 res = STRICMP(p1, p2);
1526 else
1527@@ -15274,7 +15484,8 @@
1528
1529 rettv->v_type = VAR_STRING;
1530 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf, 0);
1531- if (tofree == NULL)
1532+ /* Make a copy if we have a value but it's not in allocate memory. */
1533+ if (rettv->vval.v_string != NULL && tofree == NULL)
1534 rettv->vval.v_string = vim_strsave(rettv->vval.v_string);
1535 }
1536
1537@@ -16497,9 +16708,9 @@
1538 * Returns NULL when there is an error.
1539 */
1540 static pos_T *
1541-var2fpos(varp, lnum, fnum)
1542+var2fpos(varp, dollar_lnum, fnum)
1543 typval_T *varp;
1544- int lnum; /* TRUE when $ is last line */
1545+ int dollar_lnum; /* TRUE when $ is last line */
1546 int *fnum; /* set to fnum for '0, 'A, etc. */
1547 {
1548 char_u *name;
1549@@ -16512,6 +16723,7 @@
1550 list_T *l;
1551 int len;
1552 int error = FALSE;
1553+ listitem_T *li;
1554
1555 l = varp->vval.v_list;
1556 if (l == NULL)
1557@@ -16527,6 +16739,14 @@
1558 if (error)
1559 return NULL;
1560 len = (long)STRLEN(ml_get(pos.lnum));
1561+
1562+ /* We accept "$" for the column number: last column. */
1563+ li = list_find(l, 1L);
1564+ if (li != NULL && li->li_tv.v_type == VAR_STRING
1565+ && li->li_tv.vval.v_string != NULL
1566+ && STRCMP(li->li_tv.vval.v_string, "$") == 0)
1567+ pos.col = len + 1;
1568+
1569 /* Accept a position up to the NUL after the line. */
1570 if (pos.col == 0 || (int)pos.col > len + 1)
1571 return NULL; /* invalid column number */
1572@@ -16559,7 +16779,7 @@
1573 pos.coladd = 0;
1574 #endif
1575
1576- if (name[0] == 'w' && lnum)
1577+ if (name[0] == 'w' && dollar_lnum)
1578 {
1579 pos.col = 0;
1580 if (name[1] == '0') /* "w0": first visible line */
1581@@ -16577,7 +16797,7 @@
1582 }
1583 else if (name[0] == '$') /* last column or line */
1584 {
1585- if (lnum)
1586+ if (dollar_lnum)
1587 {
1588 pos.lnum = curbuf->b_ml.ml_line_count;
1589 pos.col = 0;
1590@@ -17798,9 +18018,10 @@
1591 * List the value of one internal variable.
1592 */
1593 static void
1594-list_one_var(v, prefix)
1595+list_one_var(v, prefix, first)
1596 dictitem_T *v;
1597 char_u *prefix;
1598+ int *first;
1599 {
1600 char_u *tofree;
1601 char_u *s;
1602@@ -17808,18 +18029,21 @@
1603
1604 s = echo_string(&v->di_tv, &tofree, numbuf, ++current_copyID);
1605 list_one_var_a(prefix, v->di_key, v->di_tv.v_type,
1606- s == NULL ? (char_u *)"" : s);
1607+ s == NULL ? (char_u *)"" : s, first);
1608 vim_free(tofree);
1609 }
1610
1611 static void
1612-list_one_var_a(prefix, name, type, string)
1613+list_one_var_a(prefix, name, type, string, first)
1614 char_u *prefix;
1615 char_u *name;
1616 int type;
1617 char_u *string;
1618+ int *first; /* when TRUE clear rest of screen and set to FALSE */
1619 {
1620- msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */
1621+ /* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */
1622+ msg_start();
1623+ msg_puts(prefix);
1624 if (name != NULL) /* "a:" vars don't have a name stored */
1625 msg_puts(name);
1626 msg_putchar(' ');
1627@@ -17847,6 +18071,11 @@
1628
1629 if (type == VAR_FUNC)
1630 msg_puts((char_u *)"()");
1631+ if (*first)
1632+ {
1633+ msg_clr_eos();
1634+ *first = FALSE;
1635+ }
1636 }
1637
1638 /*
1639@@ -19969,6 +20198,7 @@
1640 char_u buf[MSG_BUF_LEN];
1641 char_u numbuf2[NUMBUFLEN];
1642 char_u *tofree;
1643+ char_u *s;
1644
1645 msg_puts((char_u *)"(");
1646 for (i = 0; i < argcount; ++i)
1647@@ -19979,10 +20209,13 @@
1648 msg_outnum((long)argvars[i].vval.v_number);
1649 else
1650 {
1651- trunc_string(tv2string(&argvars[i], &tofree,
1652- numbuf2, 0), buf, MSG_BUF_CLEN);
1653- msg_puts(buf);
1654- vim_free(tofree);
1655+ s = tv2string(&argvars[i], &tofree, numbuf2, 0);
1656+ if (s != NULL)
1657+ {
1658+ trunc_string(s, buf, MSG_BUF_CLEN);
1659+ msg_puts(buf);
1660+ vim_free(tofree);
1661+ }
1662 }
1663 }
1664 msg_puts((char_u *)")");
1665@@ -20060,14 +20293,18 @@
1666 char_u buf[MSG_BUF_LEN];
1667 char_u numbuf2[NUMBUFLEN];
1668 char_u *tofree;
1669+ char_u *s;
1670
1671 /* The value may be very long. Skip the middle part, so that we
1672 * have some idea how it starts and ends. smsg() would always
1673 * truncate it at the end. */
1674- trunc_string(tv2string(fc.rettv, &tofree, numbuf2, 0),
1675- buf, MSG_BUF_CLEN);
1676- smsg((char_u *)_("%s returning %s"), sourcing_name, buf);
1677- vim_free(tofree);
1678+ s = tv2string(fc.rettv, &tofree, numbuf2, 0);
1679+ if (s != NULL)
1680+ {
1681+ trunc_string(s, buf, MSG_BUF_CLEN);
1682+ smsg((char_u *)_("%s returning %s"), sourcing_name, buf);
1683+ vim_free(tofree);
1684+ }
1685 }
1686 msg_puts((char_u *)"\n"); /* don't overwrite this either */
1687
1688diff -Naur vim71.orig/src/ex_cmds.c vim71/src/ex_cmds.c
1689--- vim71.orig/src/ex_cmds.c 2007-05-07 12:41:01.000000000 -0700
1690+++ vim71/src/ex_cmds.c 2007-09-03 22:15:26.000000000 -0700
1691@@ -408,7 +408,11 @@
1692 goto sortend;
1693 }
1694 *s = NUL;
1695- regmatch.regprog = vim_regcomp(p + 1, RE_MAGIC);
1696+ /* Use last search pattern if sort pattern is empty. */
1697+ if (s == p + 1 && last_search_pat() != NULL)
1698+ regmatch.regprog = vim_regcomp(last_search_pat(), RE_MAGIC);
1699+ else
1700+ regmatch.regprog = vim_regcomp(p + 1, RE_MAGIC);
1701 if (regmatch.regprog == NULL)
1702 goto sortend;
1703 p = s; /* continue after the regexp */
1704@@ -2912,22 +2916,35 @@
1705 }
1706
1707 /*
1708- * Check if a buffer is read-only. Ask for overruling in a dialog.
1709- * Return TRUE and give an error message when the buffer is readonly.
1710+ * Check if a buffer is read-only (either 'readonly' option is set or file is
1711+ * read-only). Ask for overruling in a dialog. Return TRUE and give an error
1712+ * message when the buffer is readonly.
1713 */
1714 static int
1715 check_readonly(forceit, buf)
1716 int *forceit;
1717 buf_T *buf;
1718 {
1719- if (!*forceit && buf->b_p_ro)
1720+ struct stat st;
1721+
1722+ /* Handle a file being readonly when the 'readonly' option is set or when
1723+ * the file exists and permissions are read-only.
1724+ * We will send 0777 to check_file_readonly(), as the "perm" variable is
1725+ * important for device checks but not here. */
1726+ if (!*forceit && (buf->b_p_ro
1727+ || (mch_stat((char *)buf->b_ffname, &st) >= 0
1728+ && check_file_readonly(buf->b_ffname, 0777))))
1729 {
1730 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
1731 if ((p_confirm || cmdmod.confirm) && buf->b_fname != NULL)
1732 {
1733 char_u buff[IOSIZE];
1734
1735- dialog_msg(buff, _("'readonly' option is set for \"%s\".\nDo you wish to write anyway?"),
1736+ if (buf->b_p_ro)
1737+ dialog_msg(buff, _("'readonly' option is set for \"%s\".\nDo you wish to write anyway?"),
1738+ buf->b_fname);
1739+ else
1740+ dialog_msg(buff, _("File permissions of \"%s\" are read-only.\nIt may still be possible to write it.\nDo you wish to try?"),
1741 buf->b_fname);
1742
1743 if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) == VIM_YES)
1744@@ -2941,9 +2958,14 @@
1745 }
1746 else
1747 #endif
1748+ if (buf->b_p_ro)
1749 EMSG(_(e_readonly));
1750+ else
1751+ EMSG2(_("E505: \"%s\" is read-only (add ! to override)"),
1752+ buf->b_fname);
1753 return TRUE;
1754 }
1755+
1756 return FALSE;
1757 }
1758
1759@@ -2952,7 +2974,7 @@
1760 * 'fnum' is the number of the file, if zero use ffname/sfname.
1761 *
1762 * Return 1 for "normal" error, 2 for "not written" error, 0 for success
1763- * -1 for succesfully opening another file.
1764+ * -1 for successfully opening another file.
1765 * 'lnum' is the line number for the cursor in the new file (if non-zero).
1766 */
1767 int
1768@@ -3367,7 +3389,7 @@
1769 * was in this window (or another window). If not used
1770 * before, reset the local window options to the global
1771 * values. Also restores old folding stuff. */
1772- get_winopts(buf);
1773+ get_winopts(curbuf);
1774 #ifdef FEAT_SPELL
1775 did_get_winopts = TRUE;
1776 #endif
1777@@ -3562,9 +3584,20 @@
1778 curwin_init();
1779
1780 #ifdef FEAT_FOLDING
1781- /* It's like all lines in the buffer changed. Need to update
1782- * automatic folding. */
1783+ /* It's possible that all lines in the buffer changed. Need to update
1784+ * automatic folding for all windows where it's used. */
1785+# ifdef FEAT_WINDOWS
1786+ {
1787+ win_T *win;
1788+ tabpage_T *tp;
1789+
1790+ FOR_ALL_TAB_WINDOWS(tp, win)
1791+ if (win->w_buffer == curbuf)
1792+ foldUpdateAll(win);
1793+ }
1794+# else
1795 foldUpdateAll(curwin);
1796+# endif
1797 #endif
1798
1799 /* Change directories when the 'acd' option is set. */
1800@@ -3649,8 +3682,8 @@
1801 #ifdef FEAT_SPELL
1802 /* If the window options were changed may need to set the spell language.
1803 * Can only do this after the buffer has been properly setup. */
1804- if (did_get_winopts && curwin->w_p_spell && *buf->b_p_spl != NUL)
1805- did_set_spelllang(buf);
1806+ if (did_get_winopts && curwin->w_p_spell && *curbuf->b_p_spl != NUL)
1807+ did_set_spelllang(curbuf);
1808 #endif
1809
1810 if (command == NULL)
1811@@ -3754,7 +3787,7 @@
1812 workshop_file_opened((char *)curbuf->b_ffname, curbuf->b_p_ro);
1813 # endif
1814 # ifdef FEAT_NETBEANS_INTG
1815- if (usingNetbeans & ((flags & ECMD_SET_HELP) != ECMD_SET_HELP))
1816+ if (usingNetbeans && ((flags & ECMD_SET_HELP) != ECMD_SET_HELP))
1817 netbeans_file_opened(curbuf);
1818 # endif
1819 }
1820@@ -4294,6 +4327,7 @@
1821 do_error = TRUE;
1822 do_print = FALSE;
1823 do_count = FALSE;
1824+ do_number = FALSE;
1825 do_ic = 0;
1826 }
1827 while (*cmd)
1828@@ -6351,9 +6385,9 @@
1829 for (i = 0; i < ga.ga_len; ++i)
1830 {
1831 s = ((char_u **)ga.ga_data)[i];
1832- if (STRNCMP(s, "help-tags", 9) == 0)
1833+ if (STRNCMP(s, "help-tags\t", 10) == 0)
1834 /* help-tags entry was added in formatted form */
1835- fprintf(fd_tags, (char *)s);
1836+ fputs((char *)s, fd_tags);
1837 else
1838 {
1839 fprintf(fd_tags, "%s\t/*", s);
1840diff -Naur vim71.orig/src/ex_docmd.c vim71/src/ex_docmd.c
1841--- vim71.orig/src/ex_docmd.c 2007-05-07 12:49:38.000000000 -0700
1842+++ vim71/src/ex_docmd.c 2007-09-03 22:15:22.000000000 -0700
1843@@ -133,6 +133,7 @@
1844 static void get_flags __ARGS((exarg_T *eap));
1845 #if !defined(FEAT_PERL) || !defined(FEAT_PYTHON) || !defined(FEAT_TCL) \
1846 || !defined(FEAT_RUBY) || !defined(FEAT_MZSCHEME)
1847+# define HAVE_EX_SCRIPT_NI
1848 static void ex_script_ni __ARGS((exarg_T *eap));
1849 #endif
1850 static char_u *invalid_range __ARGS((exarg_T *eap));
1851@@ -2118,7 +2119,11 @@
1852 #ifdef FEAT_USR_CMDS
1853 !USER_CMDIDX(ea.cmdidx) &&
1854 #endif
1855- cmdnames[ea.cmdidx].cmd_func == ex_ni);
1856+ (cmdnames[ea.cmdidx].cmd_func == ex_ni
1857+#ifdef HAVE_EX_SCRIPT_NI
1858+ || cmdnames[ea.cmdidx].cmd_func == ex_script_ni
1859+#endif
1860+ ));
1861
1862 #ifndef FEAT_EVAL
1863 /*
1864@@ -3276,39 +3281,65 @@
1865
1866 if (ea.argt & XFILE)
1867 {
1868- int in_quote = FALSE;
1869- char_u *bow = NULL; /* Beginning of word */
1870+ int c;
1871+ int in_quote = FALSE;
1872+ char_u *bow = NULL; /* Beginning of word */
1873
1874 /*
1875 * Allow spaces within back-quotes to count as part of the argument
1876 * being expanded.
1877 */
1878 xp->xp_pattern = skipwhite(arg);
1879- for (p = xp->xp_pattern; *p; )
1880+ p = xp->xp_pattern;
1881+ while (*p != NUL)
1882 {
1883- if (*p == '\\' && p[1] != NUL)
1884+#ifdef FEAT_MBYTE
1885+ if (has_mbyte)
1886+ c = mb_ptr2char(p);
1887+ else
1888+#endif
1889+ c = *p;
1890+ if (c == '\\' && p[1] != NUL)
1891 ++p;
1892+ else if (c == '`')
1893+ {
1894+ if (!in_quote)
1895+ {
1896+ xp->xp_pattern = p;
1897+ bow = p + 1;
1898+ }
1899+ in_quote = !in_quote;
1900+ }
1901 #ifdef SPACE_IN_FILENAME
1902- else if (vim_iswhite(*p) && (!(ea.argt & NOSPC) || usefilter))
1903+ else if (!vim_isfilec_or_wc(c)
1904+ && (!(ea.argt & NOSPC) || usefilter))
1905 #else
1906- else if (vim_iswhite(*p))
1907+ else if (!vim_isfilec_or_wc(c))
1908 #endif
1909 {
1910- p = skipwhite(p);
1911+ while (*p != NUL)
1912+ {
1913+#ifdef FEAT_MBYTE
1914+ if (has_mbyte)
1915+ c = mb_ptr2char(p);
1916+ else
1917+#endif
1918+ c = *p;
1919+ if (c == '`' || vim_isfilec_or_wc(c))
1920+ break;
1921+#ifdef FEAT_MBYTE
1922+ if (has_mbyte)
1923+ len = (*mb_ptr2len)(p);
1924+ else
1925+#endif
1926+ len = 1;
1927+ mb_ptr_adv(p);
1928+ }
1929 if (in_quote)
1930 bow = p;
1931 else
1932 xp->xp_pattern = p;
1933- --p;
1934- }
1935- else if (*p == '`')
1936- {
1937- if (!in_quote)
1938- {
1939- xp->xp_pattern = p;
1940- bow = p + 1;
1941- }
1942- in_quote = !in_quote;
1943+ p -= len;
1944 }
1945 mb_ptr_adv(p);
1946 }
1947@@ -3401,14 +3432,13 @@
1948 case CMD_windo:
1949 return arg;
1950
1951-#ifdef FEAT_SEARCH_EXTRA
1952+#ifdef FEAT_CMDL_COMPL
1953+# ifdef FEAT_SEARCH_EXTRA
1954 case CMD_match:
1955 if (*arg == NUL || !ends_excmd(*arg))
1956 {
1957- /* Dummy call to clear variables. */
1958- set_context_in_highlight_cmd(xp, (char_u *)"link n");
1959- xp->xp_context = EXPAND_HIGHLIGHT;
1960- xp->xp_pattern = arg;
1961+ /* also complete "None" */
1962+ set_context_in_echohl_cmd(xp, arg);
1963 arg = skipwhite(skiptowhite(arg));
1964 if (*arg != NUL)
1965 {
1966@@ -3417,9 +3447,8 @@
1967 }
1968 }
1969 return find_nextcmd(arg);
1970-#endif
1971+# endif
1972
1973-#ifdef FEAT_CMDL_COMPL
1974 /*
1975 * All completion for the +cmdline_compl feature goes here.
1976 */
1977@@ -3617,8 +3646,7 @@
1978 break;
1979
1980 case CMD_echohl:
1981- xp->xp_context = EXPAND_HIGHLIGHT;
1982- xp->xp_pattern = arg;
1983+ set_context_in_echohl_cmd(xp, arg);
1984 break;
1985 #endif
1986 case CMD_highlight:
1987@@ -3997,8 +4025,7 @@
1988 eap->errmsg = (char_u *)N_("E319: Sorry, the command is not available in this version");
1989 }
1990
1991-#if !defined(FEAT_PERL) || !defined(FEAT_PYTHON) || !defined(FEAT_TCL) \
1992- || !defined(FEAT_RUBY) || !defined(FEAT_MZSCHEME)
1993+#ifdef HAVE_EX_SCRIPT_NI
1994 /*
1995 * Function called for script command which is Not Implemented. NI!
1996 * Skips over ":perl <<EOF" constructs.
1997@@ -4492,7 +4519,8 @@
1998 if (eap->argt & (USECTRLV | XFILE))
1999 ++p; /* skip CTRL-V and next char */
2000 else
2001- STRCPY(p, p + 1); /* remove CTRL-V and skip next char */
2002+ /* remove CTRL-V and skip next char */
2003+ mch_memmove(p, p + 1, STRLEN(p));
2004 if (*p == NUL) /* stop at NUL after CTRL-V */
2005 break;
2006 }
2007@@ -10816,12 +10844,13 @@
2008 exarg_T *eap;
2009 {
2010 char_u *p;
2011+ char_u *g = NULL;
2012 char_u *end;
2013 int c;
2014- int mi;
2015+ int id;
2016
2017 if (eap->line2 <= 3)
2018- mi = eap->line2 - 1;
2019+ id = eap->line2;
2020 else
2021 {
2022 EMSG(e_invcmd);
2023@@ -10830,13 +10859,7 @@
2024
2025 /* First clear any old pattern. */
2026 if (!eap->skip)
2027- {
2028- vim_free(curwin->w_match[mi].regprog);
2029- curwin->w_match[mi].regprog = NULL;
2030- vim_free(curwin->w_match_pat[mi]);
2031- curwin->w_match_pat[mi] = NULL;
2032- redraw_later(SOME_VALID); /* always need a redraw */
2033- }
2034+ match_delete(curwin, id, FALSE);
2035
2036 if (ends_excmd(*eap->arg))
2037 end = eap->arg;
2038@@ -10847,15 +10870,7 @@
2039 {
2040 p = skiptowhite(eap->arg);
2041 if (!eap->skip)
2042- {
2043- curwin->w_match_id[mi] = syn_namen2id(eap->arg,
2044- (int)(p - eap->arg));
2045- if (curwin->w_match_id[mi] == 0)
2046- {
2047- EMSG2(_(e_nogroup), eap->arg);
2048- return;
2049- }
2050- }
2051+ g = vim_strnsave(eap->arg, (int)(p - eap->arg));
2052 p = skipwhite(p);
2053 if (*p == NUL)
2054 {
2055@@ -10879,14 +10894,8 @@
2056
2057 c = *end;
2058 *end = NUL;
2059- curwin->w_match[mi].regprog = vim_regcomp(p + 1, RE_MAGIC);
2060- if (curwin->w_match[mi].regprog == NULL)
2061- {
2062- EMSG2(_(e_invarg2), p);
2063- *end = c;
2064- return;
2065- }
2066- curwin->w_match_pat[mi] = vim_strsave(p + 1);
2067+ match_add(curwin, g, p + 1, 10, id);
2068+ vim_free(g);
2069 *end = c;
2070 }
2071 }
2072diff -Naur vim71.orig/src/ex_eval.c vim71/src/ex_eval.c
2073--- vim71.orig/src/ex_eval.c 2007-05-07 12:47:50.000000000 -0700
2074+++ vim71/src/ex_eval.c 2007-09-03 22:13:59.000000000 -0700
2075@@ -1551,7 +1551,7 @@
2076 }
2077 save_cpo = p_cpo;
2078 p_cpo = (char_u *)"";
2079- regmatch.regprog = vim_regcomp(pat, TRUE);
2080+ regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
2081 regmatch.rm_ic = FALSE;
2082 if (end != NULL)
2083 *end = save_char;
2084diff -Naur vim71.orig/src/ex_getln.c vim71/src/ex_getln.c
2085--- vim71.orig/src/ex_getln.c 2007-05-07 12:47:23.000000000 -0700
2086+++ vim71/src/ex_getln.c 2007-09-03 22:14:17.000000000 -0700
2087@@ -268,7 +268,9 @@
2088 {
2089 xpc.xp_context = ccline.xp_context;
2090 xpc.xp_pattern = ccline.cmdbuff;
2091+# if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)
2092 xpc.xp_arg = ccline.xp_arg;
2093+# endif
2094 }
2095 #endif
2096
2097@@ -484,7 +486,8 @@
2098 if (xpc.xp_context == EXPAND_MENUNAMES && p_wmnu)
2099 {
2100 /* Hitting <Down> after "emenu Name.": complete submenu */
2101- if (ccline.cmdbuff[ccline.cmdpos - 1] == '.' && c == K_DOWN)
2102+ if (c == K_DOWN && ccline.cmdpos > 0
2103+ && ccline.cmdbuff[ccline.cmdpos - 1] == '.')
2104 c = p_wc;
2105 else if (c == K_UP)
2106 {
2107@@ -533,9 +536,11 @@
2108 upseg[3] = PATHSEP;
2109 upseg[4] = NUL;
2110
2111- if (ccline.cmdbuff[ccline.cmdpos - 1] == PATHSEP
2112- && c == K_DOWN
2113- && (ccline.cmdbuff[ccline.cmdpos - 2] != '.'
2114+ if (c == K_DOWN
2115+ && ccline.cmdpos > 0
2116+ && ccline.cmdbuff[ccline.cmdpos - 1] == PATHSEP
2117+ && (ccline.cmdpos < 3
2118+ || ccline.cmdbuff[ccline.cmdpos - 2] != '.'
2119 || ccline.cmdbuff[ccline.cmdpos - 3] != '.'))
2120 {
2121 /* go down a directory */
2122@@ -730,8 +735,8 @@
2123 /* In Ex mode a backslash escapes a newline. */
2124 if (exmode_active
2125 && c != ESC
2126- && ccline.cmdpos > 0
2127 && ccline.cmdpos == ccline.cmdlen
2128+ && ccline.cmdpos > 0
2129 && ccline.cmdbuff[ccline.cmdpos - 1] == '\\')
2130 {
2131 if (c == K_KENTER)
2132@@ -2090,11 +2095,11 @@
2133 garray_T line_ga;
2134 char_u *pend;
2135 int startcol = 0;
2136- int c1;
2137+ int c1 = 0;
2138 int escaped = FALSE; /* CTRL-V typed */
2139 int vcol = 0;
2140 char_u *p;
2141- int prev_char = 0;
2142+ int prev_char;
2143
2144 /* Switch cursor on now. This avoids that it happens after the "\n", which
2145 * confuses the system function that computes tabstops. */
2146@@ -2147,6 +2152,7 @@
2147
2148 /* Get one character at a time. Don't use inchar(), it can't handle
2149 * special characters. */
2150+ prev_char = c1;
2151 c1 = vgetc();
2152
2153 /*
2154@@ -2204,7 +2210,6 @@
2155 redraw:
2156 /* redraw the line */
2157 msg_col = startcol;
2158- windgoto(msg_row, msg_col);
2159 vcol = 0;
2160 for (p = (char_u *)line_ga.ga_data;
2161 p < (char_u *)line_ga.ga_data + line_ga.ga_len; ++p)
2162@@ -2223,6 +2228,7 @@
2163 }
2164 }
2165 msg_clr_eos();
2166+ windgoto(msg_row, msg_col);
2167 continue;
2168 }
2169
2170@@ -2268,7 +2274,6 @@
2171 if (IS_SPECIAL(c1))
2172 c1 = '?';
2173 ((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
2174- prev_char = c1;
2175 if (c1 == '\n')
2176 msg_putchar('\n');
2177 else if (c1 == TAB)
2178@@ -4148,13 +4153,19 @@
2179
2180 #ifdef FEAT_EVAL
2181 if (ccline.cmdfirstc == '=')
2182+ {
2183+# ifdef FEAT_CMDL_COMPL
2184 /* pass CMD_SIZE because there is no real command */
2185 set_context_for_expression(xp, str, CMD_SIZE);
2186+# endif
2187+ }
2188 else if (ccline.input_fn)
2189 {
2190 xp->xp_context = ccline.xp_context;
2191 xp->xp_pattern = ccline.cmdbuff;
2192+# if defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)
2193 xp->xp_arg = ccline.xp_arg;
2194+# endif
2195 }
2196 else
2197 #endif
2198@@ -4295,10 +4306,11 @@
2199 && pat[i + 1] == '\\'
2200 && pat[i + 2] == '\\'
2201 && pat[i + 3] == ' ')
2202- STRCPY(pat + i, pat + i + 3);
2203+ mch_memmove(pat + i, pat + i + 3,
2204+ STRLEN(pat + i + 3) + 1);
2205 if (xp->xp_backslash == XP_BS_ONE
2206 && pat[i + 1] == ' ')
2207- STRCPY(pat + i, pat + i + 1);
2208+ mch_memmove(pat + i, pat + i + 1, STRLEN(pat + i));
2209 }
2210 }
2211
2212@@ -4502,6 +4514,12 @@
2213 if (xp->xp_context != EXPAND_MENUNAMES && xp->xp_context != EXPAND_MENUS)
2214 sort_strings(*file, *num_file);
2215
2216+#ifdef FEAT_CMDL_COMPL
2217+ /* Reset the variables used for special highlight names expansion, so that
2218+ * they don't show up when getting normal highlight names by ID. */
2219+ reset_expand_highlight();
2220+#endif
2221+
2222 return OK;
2223 }
2224
2225@@ -4535,7 +4553,7 @@
2226 pat = vim_strsave(filepat);
2227 for (i = 0; pat[i]; ++i)
2228 if (pat[i] == '\\' && pat[i + 1] == ' ')
2229- STRCPY(pat + i, pat + i + 1);
2230+ mch_memmove(pat + i, pat + i + 1, STRLEN(pat + i));
2231
2232 flags |= EW_FILE | EW_EXEC;
2233
2234diff -Naur vim71.orig/src/feature.h vim71/src/feature.h
2235--- vim71.orig/src/feature.h 2007-05-07 12:33:19.000000000 -0700
2236+++ vim71/src/feature.h 2007-09-03 22:14:03.000000000 -0700
2237@@ -673,7 +673,7 @@
2238 # define ESC_CHG_TO_ENG_MODE /* if defined, when ESC pressed,
2239 * turn to english mode
2240 */
2241-# if !defined(FEAT_XFONTSET) && defined(HAVE_X11)
2242+# if !defined(FEAT_XFONTSET) && defined(HAVE_X11) && !defined(HAVE_GTK2)
2243 # define FEAT_XFONTSET /* Hangul input requires xfontset */
2244 # endif
2245 # if defined(FEAT_XIM) && !defined(LINT)
2246diff -Naur vim71.orig/src/fileio.c vim71/src/fileio.c
2247--- vim71.orig/src/fileio.c 2007-05-10 04:29:44.000000000 -0700
2248+++ vim71/src/fileio.c 2007-09-03 22:14:43.000000000 -0700
2249@@ -44,6 +44,10 @@
2250 /* Is there any system that doesn't have access()? */
2251 #define USE_MCH_ACCESS
2252
2253+#if defined(sun) && defined(S_ISCHR)
2254+# define OPEN_CHR_FILES
2255+static int is_dev_fd_file(char_u *fname);
2256+#endif
2257 #ifdef FEAT_MBYTE
2258 static char_u *next_fenc __ARGS((char_u **pp));
2259 # ifdef FEAT_EVAL
2260@@ -406,6 +410,10 @@
2261 # ifdef S_ISSOCK
2262 && !S_ISSOCK(perm) /* ... or socket */
2263 # endif
2264+# ifdef OPEN_CHR_FILES
2265+ && !(S_ISCHR(perm) && is_dev_fd_file(fname))
2266+ /* ... or a character special file named /dev/fd/<n> */
2267+# endif
2268 )
2269 {
2270 if (S_ISDIR(perm))
2271@@ -424,7 +432,7 @@
2272 */
2273 if (!p_odev && mch_nodetype(fname) == NODE_WRITABLE)
2274 {
2275- filemess(curbuf, fname, (char_u *)_("is a device (disabled with 'opendevice' option"), 0);
2276+ filemess(curbuf, fname, (char_u *)_("is a device (disabled with 'opendevice' option)"), 0);
2277 msg_end();
2278 msg_scroll = msg_save;
2279 return FAIL;
2280@@ -646,6 +654,7 @@
2281 curbuf->b_start_eol = TRUE;
2282 #ifdef FEAT_MBYTE
2283 curbuf->b_p_bomb = FALSE;
2284+ curbuf->b_start_bomb = FALSE;
2285 #endif
2286 }
2287
2288@@ -904,7 +913,10 @@
2289 file_rewind = FALSE;
2290 #ifdef FEAT_MBYTE
2291 if (set_options)
2292+ {
2293 curbuf->b_p_bomb = FALSE;
2294+ curbuf->b_start_bomb = FALSE;
2295+ }
2296 conv_error = 0;
2297 #endif
2298 }
2299@@ -1353,7 +1365,10 @@
2300 size -= blen;
2301 mch_memmove(ptr, ptr + blen, (size_t)size);
2302 if (set_options)
2303+ {
2304 curbuf->b_p_bomb = TRUE;
2305+ curbuf->b_start_bomb = TRUE;
2306+ }
2307 }
2308
2309 if (fio_flags == FIO_UCSBOM)
2310@@ -2265,6 +2280,13 @@
2311 }
2312 # endif
2313 # endif
2314+# ifdef OPEN_CHR_FILES
2315+ if (S_ISCHR(perm)) /* or character special */
2316+ {
2317+ STRCAT(IObuff, _("[character special]"));
2318+ c = TRUE;
2319+ }
2320+# endif
2321 #endif
2322 if (curbuf->b_p_ro)
2323 {
2324@@ -2464,6 +2486,25 @@
2325 return OK;
2326 }
2327
2328+#ifdef OPEN_CHR_FILES
2329+/*
2330+ * Returns TRUE if the file name argument is of the form "/dev/fd/\d\+",
2331+ * which is the name of files used for process substitution output by
2332+ * some shells on some operating systems, e.g., bash on SunOS.
2333+ * Do not accept "/dev/fd/[012]", opening these may hang Vim.
2334+ */
2335+ static int
2336+is_dev_fd_file(fname)
2337+ char_u *fname;
2338+{
2339+ return (STRNCMP(fname, "/dev/fd/", 8) == 0
2340+ && VIM_ISDIGIT(fname[8])
2341+ && *skipdigits(fname + 9) == NUL
2342+ && (fname[9] != NUL
2343+ || (fname[8] != '0' && fname[8] != '1' && fname[8] != '2')));
2344+}
2345+#endif
2346+
2347 #ifdef FEAT_MBYTE
2348
2349 /*
2350@@ -2734,6 +2775,32 @@
2351 #endif
2352
2353 /*
2354+ * Return TRUE if a file appears to be read-only from the file permissions.
2355+ */
2356+ int
2357+check_file_readonly(fname, perm)
2358+ char_u *fname; /* full path to file */
2359+ int perm; /* known permissions on file */
2360+{
2361+#ifndef USE_MCH_ACCESS
2362+ int fd = 0;
2363+#endif
2364+
2365+ return (
2366+#ifdef USE_MCH_ACCESS
2367+# ifdef UNIX
2368+ (perm & 0222) == 0 ||
2369+# endif
2370+ mch_access((char *)fname, W_OK)
2371+#else
2372+ (fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0
2373+ ? TRUE : (close(fd), FALSE)
2374+#endif
2375+ );
2376+}
2377+
2378+
2379+/*
2380 * buf_write() - write to file "fname" lines "start" through "end"
2381 *
2382 * We do our own buffering here because fwrite() is so slow.
2383@@ -3219,17 +3286,8 @@
2384 * Check if the file is really writable (when renaming the file to
2385 * make a backup we won't discover it later).
2386 */
2387- file_readonly = (
2388-# ifdef USE_MCH_ACCESS
2389-# ifdef UNIX
2390- (perm & 0222) == 0 ||
2391-# endif
2392- mch_access((char *)fname, W_OK)
2393-# else
2394- (fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0
2395- ? TRUE : (close(fd), FALSE)
2396-# endif
2397- );
2398+ file_readonly = check_file_readonly(fname, (int)perm);
2399+
2400 if (!forceit && file_readonly)
2401 {
2402 if (vim_strchr(p_cpo, CPO_FWRITE) != NULL)
2403diff -Naur vim71.orig/src/globals.h vim71/src/globals.h
2404--- vim71.orig/src/globals.h 2007-05-07 12:44:26.000000000 -0700
2405+++ vim71/src/globals.h 2007-09-03 22:15:45.000000000 -0700
2406@@ -801,7 +801,7 @@
2407 EXTERN int (*mb_char2bytes) __ARGS((int c, char_u *buf)) INIT(= latin_char2bytes);
2408 EXTERN int (*mb_ptr2cells) __ARGS((char_u *p)) INIT(= latin_ptr2cells);
2409 EXTERN int (*mb_char2cells) __ARGS((int c)) INIT(= latin_char2cells);
2410-EXTERN int (*mb_off2cells) __ARGS((unsigned off)) INIT(= latin_off2cells);
2411+EXTERN int (*mb_off2cells) __ARGS((unsigned off, unsigned max_off)) INIT(= latin_off2cells);
2412 EXTERN int (*mb_ptr2char) __ARGS((char_u *p)) INIT(= latin_ptr2char);
2413 EXTERN int (*mb_head_off) __ARGS((char_u *base, char_u *p)) INIT(= latin_head_off);
2414
2415diff -Naur vim71.orig/src/gui.c vim71/src/gui.c
2416--- vim71.orig/src/gui.c 2007-05-07 12:50:55.000000000 -0700
2417+++ vim71/src/gui.c 2007-09-03 22:15:45.000000000 -0700
2418@@ -1080,7 +1080,8 @@
2419 cur_width = gui.char_width;
2420 }
2421 #ifdef FEAT_MBYTE
2422- if (has_mbyte && (*mb_off2cells)(LineOffset[gui.row] + gui.col) > 1)
2423+ if (has_mbyte && (*mb_off2cells)(LineOffset[gui.row] + gui.col,
2424+ LineOffset[gui.row] + screen_Columns) > 1)
2425 {
2426 /* Double wide character. */
2427 if (shape_table[idx].shape != SHAPE_VER)
2428@@ -1159,7 +1160,7 @@
2429 #endif
2430
2431 # if defined(FEAT_GUI_TABLINE) && (defined(FEAT_GUI_MSWIN) \
2432- || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_MAC))
2433+ || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_MAC))
2434 if (gui_has_tabline())
2435 text_area_y += gui.tabline_height;
2436 #endif
2437@@ -5117,7 +5118,7 @@
2438 p = vim_strsave_escaped(fnames[i], (char_u *)"\\ \t\"|");
2439 # endif
2440 if (p != NULL)
2441- add_to_input_buf(p, (int)STRLEN(p));
2442+ add_to_input_buf_csi(p, (int)STRLEN(p));
2443 vim_free(p);
2444 vim_free(fnames[i]);
2445 }
2446diff -Naur vim71.orig/src/gui_gtk.c vim71/src/gui_gtk.c
2447--- vim71.orig/src/gui_gtk.c 2007-05-10 01:37:37.000000000 -0700
2448+++ vim71/src/gui_gtk.c 2007-09-03 22:14:50.000000000 -0700
2449@@ -53,8 +53,8 @@
2450 # ifdef bindtextdomain
2451 # undef bindtextdomain
2452 # endif
2453-# ifdef bindtextdomain_codeset
2454-# undef bindtextdomain_codeset
2455+# ifdef bind_textdomain_codeset
2456+# undef bind_textdomain_codeset
2457 # endif
2458 # if defined(FEAT_GETTEXT) && !defined(ENABLE_NLS)
2459 # define ENABLE_NLS /* so the texts in the dialog boxes are translated */
2460@@ -1630,11 +1630,14 @@
2461 */
2462 /*ARGSUSED*/
2463 static int
2464-dlg_key_press_event(GtkWidget * widget, GdkEventKey * event, CancelData *data)
2465+dlg_key_press_event(GtkWidget *widget, GdkEventKey *event, CancelData *data)
2466 {
2467- /* Ignore hitting Enter when there is no default button. */
2468- if (data->ignore_enter && event->keyval == GDK_Return)
2469+ /* Ignore hitting Enter (or Space) when there is no default button. */
2470+ if (data->ignore_enter && (event->keyval == GDK_Return
2471+ || event->keyval == ' '))
2472 return TRUE;
2473+ else /* A different key was pressed, return to normal behavior */
2474+ data->ignore_enter = FALSE;
2475
2476 if (event->keyval != GDK_Escape && event->keyval != GDK_Return)
2477 return FALSE;
2478@@ -2224,6 +2227,13 @@
2479 {
2480 DialogInfo *di = (DialogInfo *)data;
2481
2482+ /* Ignore hitting Enter (or Space) when there is no default button. */
2483+ if (di->ignore_enter && (event->keyval == GDK_Return
2484+ || event->keyval == ' '))
2485+ return TRUE;
2486+ else /* A different key was pressed, return to normal behavior */
2487+ di->ignore_enter = FALSE;
2488+
2489 /* Close the dialog when hitting "Esc". */
2490 if (event->keyval == GDK_Escape)
2491 {
2492diff -Naur vim71.orig/src/gui_gtk_x11.c vim71/src/gui_gtk_x11.c
2493--- vim71.orig/src/gui_gtk_x11.c 2007-05-10 01:37:49.000000000 -0700
2494+++ vim71/src/gui_gtk_x11.c 2007-09-03 22:12:35.000000000 -0700
2495@@ -36,8 +36,8 @@
2496 # ifdef bindtextdomain
2497 # undef bindtextdomain
2498 # endif
2499-# ifdef bindtextdomain_codeset
2500-# undef bindtextdomain_codeset
2501+# ifdef bind_textdomain_codeset
2502+# undef bind_textdomain_codeset
2503 # endif
2504 # if defined(FEAT_GETTEXT) && !defined(ENABLE_NLS)
2505 # define ENABLE_NLS /* so the texts in the dialog boxes are translated */
2506@@ -2188,8 +2188,10 @@
2507 escaped_filename = vim_strsave_escaped(filename, escape_chars);
2508 if (escaped_filename == NULL)
2509 return FALSE;
2510- mksession_cmdline = g_strconcat("mksession ", (char *)escaped_filename, NULL);
2511+ mksession_cmdline = g_strconcat("mksession ", (char *)escaped_filename,
2512+ NULL);
2513 vim_free(escaped_filename);
2514+
2515 /*
2516 * Use a reasonable hardcoded set of 'sessionoptions' flags to avoid
2517 * unpredictable effects when the session is saved automatically. Also,
2518@@ -2199,7 +2201,7 @@
2519 */
2520 save_ssop_flags = ssop_flags;
2521 ssop_flags = (SSOP_BLANK|SSOP_CURDIR|SSOP_FOLDS|SSOP_GLOBALS
2522- |SSOP_HELP|SSOP_OPTIONS|SSOP_WINSIZE);
2523+ |SSOP_HELP|SSOP_OPTIONS|SSOP_WINSIZE|SSOP_TABPAGES);
2524
2525 do_cmdline_cmd((char_u *)"let Save_VV_this_session = v:this_session");
2526 failed = (do_cmdline_cmd((char_u *)mksession_cmdline) == FAIL);
2527diff -Naur vim71.orig/src/if_cscope.c vim71/src/if_cscope.c
2528--- vim71.orig/src/if_cscope.c 2007-03-11 07:29:57.000000000 -0700
2529+++ vim71/src/if_cscope.c 2007-09-03 22:15:31.000000000 -0700
2530@@ -73,6 +73,8 @@
2531
2532
2533 static csinfo_T csinfo[CSCOPE_MAX_CONNECTIONS];
2534+static int eap_arg_len; /* length of eap->arg, set in
2535+ cs_lookup_cmd() */
2536 static cscmd_T cs_cmds[] =
2537 {
2538 { "add", cs_add,
2539@@ -260,14 +262,7 @@
2540
2541 if ((p = cs_manage_matches(NULL, NULL, -1, Get)) == NULL)
2542 return TRUE;
2543-
2544- if ((int)strlen(p) > size)
2545- {
2546- strncpy((char *)buf, p, size - 1);
2547- buf[size] = '\0';
2548- }
2549- else
2550- (void)strcpy((char *)buf, p);
2551+ vim_strncpy(buf, (char_u *)p, size - 1);
2552
2553 return FALSE;
2554 } /* cs_fgets */
2555@@ -386,7 +381,7 @@
2556 * PRIVATE: cs_add
2557 *
2558 * add cscope database or a directory name (to look for cscope.out)
2559- * the the cscope connection list
2560+ * to the cscope connection list
2561 *
2562 * MAXPATHL 256
2563 */
2564@@ -966,7 +961,7 @@
2565 }
2566
2567 pat = opt + strlen(opt) + 1;
2568- if (pat == NULL || (pat != NULL && pat[0] == '\0'))
2569+ if (pat >= (char *)eap->arg + eap_arg_len)
2570 {
2571 cs_usage_msg(Find);
2572 return FALSE;
2573@@ -1317,7 +1312,7 @@
2574 #else
2575 /* compare pathnames first */
2576 && ((fullpathcmp(csinfo[j].fname, fname, FALSE) & FPC_SAME)
2577- /* if not Windows 9x, test index file atributes too */
2578+ /* if not Windows 9x, test index file attributes too */
2579 || (!mch_windows95()
2580 && csinfo[j].nVolume == bhfi.dwVolumeSerialNumber
2581 && csinfo[j].nIndexHigh == bhfi.nFileIndexHigh
2582@@ -1401,6 +1396,9 @@
2583 if (eap->arg == NULL)
2584 return NULL;
2585
2586+ /* Store length of eap->arg before it gets modified by strtok(). */
2587+ eap_arg_len = STRLEN(eap->arg);
2588+
2589 if ((stok = strtok((char *)(eap->arg), (const char *)" ")) == NULL)
2590 return NULL;
2591
2592@@ -2195,7 +2193,7 @@
2593 cs_add_common(dblist[i], pplist[i], fllist[i]);
2594 if (p_csverbose)
2595 {
2596- /* dont' use smsg_attr because want to display
2597+ /* don't use smsg_attr() because we want to display the
2598 * connection number in the same line as
2599 * "Added cscope database..."
2600 */
2601diff -Naur vim71.orig/src/if_mzsch.c vim71/src/if_mzsch.c
2602--- vim71.orig/src/if_mzsch.c 2007-05-12 04:13:47.000000000 -0700
2603+++ vim71/src/if_mzsch.c 2007-09-03 22:12:59.000000000 -0700
2604@@ -308,6 +308,8 @@
2605 static Scheme_Config *(*dll_scheme_current_config)(void);
2606 static Scheme_Object *(*dll_scheme_char_string_to_byte_string)
2607 (Scheme_Object *s);
2608+static Scheme_Object *(*dll_scheme_char_string_to_path)
2609+ (Scheme_Object *s);
2610 # endif
2611
2612 /* arrays are imported directly */
2613@@ -398,6 +400,8 @@
2614 # define scheme_current_config dll_scheme_current_config
2615 # define scheme_char_string_to_byte_string \
2616 dll_scheme_char_string_to_byte_string
2617+# define scheme_char_string_to_path \
2618+ dll_scheme_char_string_to_path
2619 # endif
2620
2621 typedef struct
2622@@ -498,6 +502,8 @@
2623 {"scheme_current_config", (void **)&dll_scheme_current_config},
2624 {"scheme_char_string_to_byte_string",
2625 (void **)&dll_scheme_char_string_to_byte_string},
2626+ {"scheme_char_string_to_path",
2627+ (void **)&dll_scheme_char_string_to_path},
2628 # endif
2629 {NULL, NULL}};
2630
2631@@ -773,7 +779,14 @@
2632 #ifdef MZSCHEME_COLLECTS
2633 /* setup 'current-library-collection-paths' parameter */
2634 scheme_set_param(scheme_config, MZCONFIG_COLLECTION_PATHS,
2635- scheme_make_pair(scheme_make_string(MZSCHEME_COLLECTS),
2636+ scheme_make_pair(
2637+# if MZSCHEME_VERSION_MAJOR >= 299
2638+ scheme_char_string_to_path(
2639+ scheme_byte_string_to_char_string(
2640+ scheme_make_byte_string(MZSCHEME_COLLECTS))),
2641+# else
2642+ scheme_make_string(MZSCHEME_COLLECTS),
2643+# endif
2644 scheme_null));
2645 #endif
2646 #ifdef HAVE_SANDBOX
2647diff -Naur vim71.orig/src/macros.h vim71/src/macros.h
2648--- vim71.orig/src/macros.h 2007-05-07 12:38:22.000000000 -0700
2649+++ vim71/src/macros.h 2007-09-03 22:15:12.000000000 -0700
2650@@ -54,10 +54,12 @@
2651
2652 /*
2653 * toupper() and tolower() that use the current locale.
2654- * On some systems toupper()/tolower() only work on lower/uppercase characters
2655+ * On some systems toupper()/tolower() only work on lower/uppercase
2656+ * characters, first use islower() or isupper() then.
2657 * Careful: Only call TOUPPER_LOC() and TOLOWER_LOC() with a character in the
2658 * range 0 - 255. toupper()/tolower() on some systems can't handle others.
2659- * Note: for UTF-8 use utf_toupper() and utf_tolower().
2660+ * Note: It is often better to use MB_TOLOWER() and MB_TOUPPER(), because many
2661+ * toupper() and tolower() implementations only work for ASCII.
2662 */
2663 #ifdef MSWIN
2664 # define TOUPPER_LOC(c) toupper_tab[(c) & 255]
2665diff -Naur vim71.orig/src/main.c vim71/src/main.c
2666--- vim71.orig/src/main.c 2007-05-07 12:38:44.000000000 -0700
2667+++ vim71/src/main.c 2007-09-03 22:14:26.000000000 -0700
2668@@ -954,7 +954,8 @@
2669 int cmdwin; /* TRUE when working in the command-line window */
2670 int noexmode; /* TRUE when return on entering Ex mode */
2671 {
2672- oparg_T oa; /* operator arguments */
2673+ oparg_T oa; /* operator arguments */
2674+ int previous_got_int = FALSE; /* "got_int" was TRUE */
2675
2676 #if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
2677 /* Setup to catch a terminating error from the X server. Just ignore
2678@@ -1015,12 +1016,32 @@
2679 need_fileinfo = FALSE;
2680 }
2681 }
2682- if (got_int && !global_busy)
2683+
2684+ /* Reset "got_int" now that we got back to the main loop. Except when
2685+ * inside a ":g/pat/cmd" command, then the "got_int" needs to abort
2686+ * the ":g" command.
2687+ * For ":g/pat/vi" we reset "got_int" when used once. When used
2688+ * a second time we go back to Ex mode and abort the ":g" command. */
2689+ if (got_int)
2690 {
2691- if (!quit_more)
2692- (void)vgetc(); /* flush all buffers */
2693- got_int = FALSE;
2694+ if (noexmode && global_busy && !exmode_active && previous_got_int)
2695+ {
2696+ /* Typed two CTRL-C in a row: go back to ex mode as if "Q" was
2697+ * used and keep "got_int" set, so that it aborts ":g". */
2698+ exmode_active = EXMODE_NORMAL;
2699+ State = NORMAL;
2700+ }
2701+ else if (!global_busy || !exmode_active)
2702+ {
2703+ if (!quit_more)
2704+ (void)vgetc(); /* flush all buffers */
2705+ got_int = FALSE;
2706+ }
2707+ previous_got_int = TRUE;
2708 }
2709+ else
2710+ previous_got_int = FALSE;
2711+
2712 if (!exmode_active)
2713 msg_scroll = FALSE;
2714 quit_more = FALSE;
2715@@ -1360,8 +1381,7 @@
2716 p = vim_getenv((char_u *)"VIMRUNTIME", &mustfree);
2717 if (p != NULL && *p != NUL)
2718 {
2719- STRCPY(NameBuff, p);
2720- STRCAT(NameBuff, "/lang");
2721+ vim_snprintf((char *)NameBuff, MAXPATHL, "%s/lang", p);
2722 bindtextdomain(VIMPACKAGE, (char *)NameBuff);
2723 }
2724 if (mustfree)
2725diff -Naur vim71.orig/src/mbyte.c vim71/src/mbyte.c
2726--- vim71.orig/src/mbyte.c 2007-05-07 12:47:09.000000000 -0700
2727+++ vim71/src/mbyte.c 2007-09-03 22:15:45.000000000 -0700
2728@@ -1310,20 +1310,26 @@
2729 /*
2730 * mb_off2cells() function pointer.
2731 * Return number of display cells for char at ScreenLines[off].
2732- * Caller must make sure "off" and "off + 1" are valid!
2733+ * We make sure that the offset used is less than "max_off".
2734 */
2735 /*ARGSUSED*/
2736 int
2737-latin_off2cells(off)
2738+latin_off2cells(off, max_off)
2739 unsigned off;
2740+ unsigned max_off;
2741 {
2742 return 1;
2743 }
2744
2745 int
2746-dbcs_off2cells(off)
2747+dbcs_off2cells(off, max_off)
2748 unsigned off;
2749+ unsigned max_off;
2750 {
2751+ /* never check beyond end of the line */
2752+ if (off >= max_off)
2753+ return 1;
2754+
2755 /* Number of cells is equal to number of bytes, except for euc-jp when
2756 * the first byte is 0x8e. */
2757 if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e)
2758@@ -1332,10 +1338,11 @@
2759 }
2760
2761 int
2762-utf_off2cells(off)
2763+utf_off2cells(off, max_off)
2764 unsigned off;
2765+ unsigned max_off;
2766 {
2767- return ScreenLines[off + 1] == 0 ? 2 : 1;
2768+ return (off + 1 < max_off && ScreenLines[off + 1] == 0) ? 2 : 1;
2769 }
2770
2771 /*
2772@@ -2320,7 +2327,7 @@
2773 /* Single byte: first check normally, then with ignore case. */
2774 if (s1[i] != s2[i])
2775 {
2776- cdiff = TOLOWER_LOC(s1[i]) - TOLOWER_LOC(s2[i]);
2777+ cdiff = MB_TOLOWER(s1[i]) - MB_TOLOWER(s2[i]);
2778 if (cdiff != 0)
2779 return cdiff;
2780 }
2781@@ -2899,12 +2906,8 @@
2782 if (composing_hangul)
2783 return TRUE;
2784 #endif
2785- if (enc_dbcs != 0)
2786- return dbcs_off2cells(LineOffset[row] + col) > 1;
2787- if (enc_utf8)
2788- return (col + 1 < Columns
2789- && ScreenLines[LineOffset[row] + col + 1] == 0);
2790- return FALSE;
2791+ return (*mb_off2cells)(LineOffset[row] + col,
2792+ LineOffset[row] + screen_Columns) > 1;
2793 }
2794
2795 # if defined(FEAT_CLIPBOARD) || defined(FEAT_GUI) || defined(FEAT_RIGHTLEFT) \
2796diff -Naur vim71.orig/src/message.c vim71/src/message.c
2797--- vim71.orig/src/message.c 2007-05-07 12:31:59.000000000 -0700
2798+++ vim71/src/message.c 2007-09-03 22:14:19.000000000 -0700
2799@@ -1842,7 +1842,7 @@
2800 int wrap;
2801
2802 did_wait_return = FALSE;
2803- while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
2804+ while ((maxlen < 0 || (int)(s - str) < maxlen) && *s != NUL)
2805 {
2806 /*
2807 * We are at the end of the screen line when:
2808@@ -1878,7 +1878,7 @@
2809 /* output postponed text */
2810 t_puts(&t_col, t_s, s, attr);
2811
2812- /* When no more prompt an no more room, truncate here */
2813+ /* When no more prompt and no more room, truncate here */
2814 if (msg_no_more && lines_left == 0)
2815 break;
2816
2817@@ -1927,7 +1927,8 @@
2818 * If screen is completely filled and 'more' is set then wait
2819 * for a character.
2820 */
2821- --lines_left;
2822+ if (lines_left > 0)
2823+ --lines_left;
2824 if (p_more && lines_left == 0 && State != HITRETURN
2825 && !msg_no_more && !exmode_active)
2826 {
2827@@ -2234,7 +2235,7 @@
2828 {
2829 msgchunk_T *mp;
2830
2831- /* Only show somethign if there is more than one line, otherwise it looks
2832+ /* Only show something if there is more than one line, otherwise it looks
2833 * weird, typing a command without output results in one line. */
2834 mp = msg_sb_start(last_msgchunk);
2835 if (mp == NULL || mp->sb_prev == NULL)
2836@@ -2622,7 +2623,7 @@
2837 }
2838 }
2839
2840- if (scroll < 0 || (scroll == 0 && mp_last != NULL))
2841+ if (scroll <= 0)
2842 {
2843 /* displayed the requested text, more prompt again */
2844 screen_fill((int)Rows - 1, (int)Rows, 0,
2845@@ -3456,11 +3457,11 @@
2846 /* advance to next hotkey and set default hotkey */
2847 #ifdef FEAT_MBYTE
2848 if (has_mbyte)
2849- hotkp += (*mb_ptr2len)(hotkp);
2850+ hotkp += STRLEN(hotkp);
2851 else
2852 #endif
2853 ++hotkp;
2854- (void)copy_char(r + 1, hotkp, TRUE);
2855+ hotkp[copy_char(r + 1, hotkp, TRUE)] = NUL;
2856 if (dfltbutton)
2857 --dfltbutton;
2858
2859@@ -3493,7 +3494,7 @@
2860 *msgp++ = (dfltbutton == 1) ? ']' : ')';
2861
2862 /* redefine hotkey */
2863- (void)copy_char(r, hotkp, TRUE);
2864+ hotkp[copy_char(r, hotkp, TRUE)] = NUL;
2865 }
2866 }
2867 else
2868@@ -3519,8 +3520,6 @@
2869 *msgp++ = ':';
2870 *msgp++ = ' ';
2871 *msgp = NUL;
2872- mb_ptr_adv(hotkp);
2873- *hotkp = NUL;
2874 }
2875 else
2876 {
2877@@ -3555,8 +3554,9 @@
2878 msgp = confirm_msg + 1 + STRLEN(message);
2879 hotkp = hotk;
2880
2881- /* define first default hotkey */
2882- (void)copy_char(buttons, hotkp, TRUE);
2883+ /* Define first default hotkey. Keep the hotkey string NUL
2884+ * terminated to avoid reading past the end. */
2885+ hotkp[copy_char(buttons, hotkp, TRUE)] = NUL;
2886
2887 /* Remember where the choices start, displaying starts here when
2888 * "hotkp" typed at the more prompt. */
2889diff -Naur vim71.orig/src/misc1.c vim71/src/misc1.c
2890--- vim71.orig/src/misc1.c 2007-05-07 12:49:03.000000000 -0700
2891+++ vim71/src/misc1.c 2007-09-03 22:14:59.000000000 -0700
2892@@ -90,7 +90,7 @@
2893 */
2894 int
2895 set_indent(size, flags)
2896- int size;
2897+ int size; /* measured in spaces */
2898 int flags;
2899 {
2900 char_u *p;
2901@@ -98,12 +98,14 @@
2902 char_u *oldline;
2903 char_u *s;
2904 int todo;
2905- int ind_len;
2906+ int ind_len; /* measured in characters */
2907 int line_len;
2908 int doit = FALSE;
2909- int ind_done;
2910+ int ind_done = 0; /* measured in spaces */
2911 int tab_pad;
2912 int retval = FALSE;
2913+ int orig_char_len = -1; /* number of initial whitespace chars when
2914+ 'et' and 'pi' are both set */
2915
2916 /*
2917 * First check if there is anything to do and compute the number of
2918@@ -116,8 +118,10 @@
2919 /* Calculate the buffer size for the new indent, and check to see if it
2920 * isn't already set */
2921
2922- /* if 'expandtab' isn't set: use TABs */
2923- if (!curbuf->b_p_et)
2924+ /* if 'expandtab' isn't set: use TABs; if both 'expandtab' and
2925+ * 'preserveindent' are set count the number of characters at the
2926+ * beginning of the line to be copied */
2927+ if (!curbuf->b_p_et || (!(flags & SIN_INSERT) && curbuf->b_p_pi))
2928 {
2929 /* If 'preserveindent' is set then reuse as much as possible of
2930 * the existing indent structure for the new indent */
2931@@ -148,9 +152,14 @@
2932 ++p;
2933 }
2934
2935+ /* Set initial number of whitespace chars to copy if we are
2936+ * preserving indent but expandtab is set */
2937+ if (curbuf->b_p_et)
2938+ orig_char_len = ind_len;
2939+
2940 /* Fill to next tabstop with a tab, if possible */
2941 tab_pad = (int)curbuf->b_p_ts - (ind_done % (int)curbuf->b_p_ts);
2942- if (todo >= tab_pad)
2943+ if (todo >= tab_pad && orig_char_len == -1)
2944 {
2945 doit = TRUE;
2946 todo -= tab_pad;
2947@@ -193,13 +202,42 @@
2948 else
2949 p = skipwhite(p);
2950 line_len = (int)STRLEN(p) + 1;
2951- newline = alloc(ind_len + line_len);
2952- if (newline == NULL)
2953- return FALSE;
2954+
2955+ /* If 'preserveindent' and 'expandtab' are both set keep the original
2956+ * characters and allocate accordingly. We will fill the rest with spaces
2957+ * after the if (!curbuf->b_p_et) below. */
2958+ if (orig_char_len != -1)
2959+ {
2960+ newline = alloc(orig_char_len + size - ind_done + line_len);
2961+ if (newline == NULL)
2962+ return FALSE;
2963+ todo = size - ind_done;
2964+ ind_len = orig_char_len + todo; /* Set total length of indent in
2965+ * characters, which may have been
2966+ * undercounted until now */
2967+ p = oldline;
2968+ s = newline;
2969+ while (orig_char_len > 0)
2970+ {
2971+ *s++ = *p++;
2972+ orig_char_len--;
2973+ }
2974+ /* Skip over any additional white space (useful when newindent is less
2975+ * than old) */
2976+ while (vim_iswhite(*p))
2977+ (void)*p++;
2978+
2979+ }
2980+ else
2981+ {
2982+ todo = size;
2983+ newline = alloc(ind_len + line_len);
2984+ if (newline == NULL)
2985+ return FALSE;
2986+ s = newline;
2987+ }
2988
2989 /* Put the characters in the new line. */
2990- s = newline;
2991- todo = size;
2992 /* if 'expandtab' isn't set: use TABs */
2993 if (!curbuf->b_p_et)
2994 {
2995@@ -1320,8 +1358,8 @@
2996 newindent += (int)curbuf->b_p_sw;
2997 }
2998 #endif
2999- /* Copy the indent only if expand tab is disabled */
3000- if (curbuf->b_p_ci && !curbuf->b_p_et)
3001+ /* Copy the indent */
3002+ if (curbuf->b_p_ci)
3003 {
3004 (void)copy_indent(newindent, saved_line);
3005
3006@@ -4786,7 +4824,7 @@
3007 static int cin_iswhileofdo __ARGS((char_u *, linenr_T, int));
3008 static int cin_iswhileofdo_end __ARGS((int terminated, int ind_maxparen, int ind_maxcomment));
3009 static int cin_isbreak __ARGS((char_u *));
3010-static int cin_is_cpp_baseclass __ARGS((char_u *line, colnr_T *col));
3011+static int cin_is_cpp_baseclass __ARGS((colnr_T *col));
3012 static int get_baseclass_amount __ARGS((int col, int ind_maxparen, int ind_maxcomment, int ind_cpp_baseclass));
3013 static int cin_ends_in __ARGS((char_u *, char_u *, char_u *));
3014 static int cin_skip2pos __ARGS((pos_T *trypos));
3015@@ -5551,13 +5589,13 @@
3016 * This is a lot of guessing. Watch out for "cond ? func() : foo".
3017 */
3018 static int
3019-cin_is_cpp_baseclass(line, col)
3020- char_u *line;
3021+cin_is_cpp_baseclass(col)
3022 colnr_T *col; /* return: column to align with */
3023 {
3024 char_u *s;
3025 int class_or_struct, lookfor_ctor_init, cpp_base_class;
3026 linenr_T lnum = curwin->w_cursor.lnum;
3027+ char_u *line = ml_get_curline();
3028
3029 *col = 0;
3030
3031@@ -5585,7 +5623,8 @@
3032 */
3033 while (lnum > 1)
3034 {
3035- s = skipwhite(ml_get(lnum - 1));
3036+ line = ml_get(lnum - 1);
3037+ s = skipwhite(line);
3038 if (*s == '#' || *s == NUL)
3039 break;
3040 while (*s != NUL)
3041@@ -5602,7 +5641,8 @@
3042 --lnum;
3043 }
3044
3045- s = cin_skipcomment(ml_get(lnum));
3046+ line = ml_get(lnum);
3047+ s = cin_skipcomment(line);
3048 for (;;)
3049 {
3050 if (*s == NUL)
3051@@ -5610,7 +5650,10 @@
3052 if (lnum == curwin->w_cursor.lnum)
3053 break;
3054 /* Continue in the cursor line. */
3055- s = cin_skipcomment(ml_get(++lnum));
3056+ line = ml_get(++lnum);
3057+ s = cin_skipcomment(line);
3058+ if (*s == NUL)
3059+ continue;
3060 }
3061
3062 if (s[0] == ':')
3063@@ -7079,7 +7122,7 @@
3064 n = FALSE;
3065 if (lookfor != LOOKFOR_TERM && ind_cpp_baseclass > 0)
3066 {
3067- n = cin_is_cpp_baseclass(l, &col);
3068+ n = cin_is_cpp_baseclass(&col);
3069 l = ml_get_curline();
3070 }
3071 if (n)
3072@@ -7670,7 +7713,7 @@
3073 n = FALSE;
3074 if (ind_cpp_baseclass != 0 && theline[0] != '{')
3075 {
3076- n = cin_is_cpp_baseclass(l, &col);
3077+ n = cin_is_cpp_baseclass(&col);
3078 l = ml_get_curline();
3079 }
3080 if (n)
3081@@ -8596,7 +8639,7 @@
3082 for (p = buf + wildoff; p < s; ++p)
3083 if (rem_backslash(p))
3084 {
3085- STRCPY(p, p + 1);
3086+ mch_memmove(p, p + 1, STRLEN(p));
3087 --e;
3088 --s;
3089 }
3090@@ -8897,7 +8940,7 @@
3091 for (p = buf + wildoff; p < s; ++p)
3092 if (rem_backslash(p))
3093 {
3094- STRCPY(p, p + 1);
3095+ mch_memmove(p, p + 1, STRLEN(p));
3096 --e;
3097 --s;
3098 }
3099diff -Naur vim71.orig/src/normal.c vim71/src/normal.c
3100--- vim71.orig/src/normal.c 2007-05-07 12:34:39.000000000 -0700
3101+++ vim71/src/normal.c 2007-09-03 22:15:06.000000000 -0700
3102@@ -889,6 +889,11 @@
3103
3104 ++no_mapping;
3105 ++allow_keys; /* no mapping for nchar, but allow key codes */
3106+#ifdef FEAT_AUTOCMD
3107+ /* Don't generate a CursorHold event here, most commands can't handle
3108+ * it, e.g., nv_replace(), nv_csearch(). */
3109+ did_cursorhold = TRUE;
3110+#endif
3111 if (ca.cmdchar == 'g')
3112 {
3113 /*
3114@@ -3755,7 +3760,8 @@
3115 extra_len = (int)STRLEN(p);
3116 overflow = old_len + extra_len - SHOWCMD_COLS;
3117 if (overflow > 0)
3118- STRCPY(showcmd_buf, showcmd_buf + overflow);
3119+ mch_memmove(showcmd_buf, showcmd_buf + overflow,
3120+ old_len - overflow + 1);
3121 STRCAT(showcmd_buf, p);
3122
3123 if (char_avail())
3124@@ -6379,7 +6385,7 @@
3125 */
3126 else if (cap->nchar == 'p' || cap->nchar == 'P')
3127 {
3128- if (!checkclearopq(cap->oap))
3129+ if (!checkclearop(cap->oap))
3130 {
3131 prep_redo_cmd(cap);
3132 do_put(cap->oap->regname,
3133@@ -6662,6 +6668,13 @@
3134 else
3135 had_ctrl_v = NUL;
3136
3137+ /* Abort if the character is a special key. */
3138+ if (IS_SPECIAL(cap->nchar))
3139+ {
3140+ clearopbeep(cap->oap);
3141+ return;
3142+ }
3143+
3144 #ifdef FEAT_VISUAL
3145 /* Visual mode "r" */
3146 if (VIsual_active)
3147@@ -6688,11 +6701,9 @@
3148 }
3149 #endif
3150
3151- /*
3152- * Check for a special key or not enough characters to replace.
3153- */
3154+ /* Abort if not enough characters to replace. */
3155 ptr = ml_get_cursor();
3156- if (IS_SPECIAL(cap->nchar) || STRLEN(ptr) < (unsigned)cap->count1
3157+ if (STRLEN(ptr) < (unsigned)cap->count1
3158 #ifdef FEAT_MBYTE
3159 || (has_mbyte && mb_charlen(ptr) < cap->count1)
3160 #endif
3161diff -Naur vim71.orig/src/ops.c vim71/src/ops.c
3162--- vim71.orig/src/ops.c 2007-05-07 12:33:47.000000000 -0700
3163+++ vim71/src/ops.c 2007-09-03 22:12:53.000000000 -0700
3164@@ -3404,7 +3404,9 @@
3165
3166 #ifdef FEAT_VIRTUALEDIT
3167 col += curwin->w_cursor.coladd;
3168- if (ve_flags == VE_ALL && curwin->w_cursor.coladd > 0)
3169+ if (ve_flags == VE_ALL
3170+ && (curwin->w_cursor.coladd > 0
3171+ || endcol2 == curwin->w_cursor.col))
3172 {
3173 if (dir == FORWARD && c == NUL)
3174 ++col;
3175diff -Naur vim71.orig/src/option.c vim71/src/option.c
3176--- vim71.orig/src/option.c 2007-05-01 04:26:10.000000000 -0700
3177+++ vim71/src/option.c 2007-09-03 22:14:43.000000000 -0700
3178@@ -4628,7 +4628,7 @@
3179 if ((!(flags & P_COMMA) || *s != ',')
3180 && vim_strchr(s + 1, *s) != NULL)
3181 {
3182- STRCPY(s, s + 1);
3183+ mch_memmove(s, s + 1, STRLEN(s));
3184 --s;
3185 }
3186 }
3187@@ -7118,6 +7118,11 @@
3188 /* when 'endofline' is changed, redraw the window title */
3189 else if ((int *)varp == &curbuf->b_p_eol)
3190 need_maketitle = TRUE;
3191+#ifdef FEAT_MBYTE
3192+ /* when 'bomb' is changed, redraw the window title */
3193+ else if ((int *)varp == &curbuf->b_p_bomb)
3194+ need_maketitle = TRUE;
3195+#endif
3196 #endif
3197
3198 /* when 'bin' is set also set some other options */
3199@@ -8219,6 +8224,25 @@
3200 varp = get_varp(&options[opt_idx]);
3201 if (varp != NULL) /* hidden option is not changed */
3202 {
3203+ if (number == 0 && string != NULL)
3204+ {
3205+ int index;
3206+
3207+ /* Either we are given a string or we are setting option
3208+ * to zero. */
3209+ for (index = 0; string[index] == '0'; ++index)
3210+ ;
3211+ if (string[index] != NUL || index == 0)
3212+ {
3213+ /* There's another character after zeros or the string
3214+ * is empty. In both cases, we are trying to set a
3215+ * num option using a string. */
3216+ EMSG3(_("E521: Number required: &%s = '%s'"),
3217+ name, string);
3218+ return; /* do nothing as we hit an error */
3219+
3220+ }
3221+ }
3222 if (flags & P_NUM)
3223 (void)set_num_option(opt_idx, varp, number,
3224 NULL, 0, opt_flags);
3225@@ -10585,6 +10609,8 @@
3226 buf->b_start_ffc = *buf->b_p_ff;
3227 buf->b_start_eol = buf->b_p_eol;
3228 #ifdef FEAT_MBYTE
3229+ buf->b_start_bomb = buf->b_p_bomb;
3230+
3231 /* Only use free/alloc when necessary, they take time. */
3232 if (buf->b_start_fenc == NULL
3233 || STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0)
3234@@ -10598,13 +10624,17 @@
3235 /*
3236 * Return TRUE if 'fileformat' and/or 'fileencoding' has a different value
3237 * from when editing started (save_file_ff() called).
3238- * Also when 'endofline' was changed and 'binary' is set.
3239+ * Also when 'endofline' was changed and 'binary' is set, or when 'bomb' was
3240+ * changed and 'binary' is not set.
3241 * Don't consider a new, empty buffer to be changed.
3242 */
3243 int
3244 file_ff_differs(buf)
3245 buf_T *buf;
3246 {
3247+ /* In a buffer that was never loaded the options are not valid. */
3248+ if (buf->b_flags & BF_NEVERLOADED)
3249+ return FALSE;
3250 if ((buf->b_flags & BF_NEW)
3251 && buf->b_ml.ml_line_count == 1
3252 && *ml_get_buf(buf, (linenr_T)1, FALSE) == NUL)
3253@@ -10614,6 +10644,8 @@
3254 if (buf->b_p_bin && buf->b_start_eol != buf->b_p_eol)
3255 return TRUE;
3256 #ifdef FEAT_MBYTE
3257+ if (!buf->b_p_bin && buf->b_start_bomb != buf->b_p_bomb)
3258+ return TRUE;
3259 if (buf->b_start_fenc == NULL)
3260 return (*buf->b_p_fenc != NUL);
3261 return (STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0);
3262diff -Naur vim71.orig/src/os_unix.c vim71/src/os_unix.c
3263--- vim71.orig/src/os_unix.c 2007-05-09 12:41:58.000000000 -0700
3264+++ vim71/src/os_unix.c 2007-09-03 22:15:38.000000000 -0700
3265@@ -753,7 +753,8 @@
3266 if (signal_stack != NULL)
3267 {
3268 # ifdef HAVE_SIGALTSTACK
3269-# ifdef __APPLE__
3270+# if defined(__APPLE__) && (!defined(MAC_OS_X_VERSION_MAX_ALLOWED) \
3271+ || MAC_OS_X_VERSION_MAX_ALLOWED <= 1040)
3272 /* missing prototype. Adding it to osdef?.h.in doesn't work, because
3273 * "struct sigaltstack" needs to be declared. */
3274 extern int sigaltstack __ARGS((const struct sigaltstack *ss, struct sigaltstack *oss));
3275@@ -2499,7 +2500,13 @@
3276 if (stat((char *)name, &statb))
3277 #endif
3278 return -1;
3279+#ifdef __INTERIX
3280+ /* The top bit makes the value negative, which means the file doesn't
3281+ * exist. Remove the bit, we don't use it. */
3282+ return statb.st_mode & ~S_ADDACE;
3283+#else
3284 return statb.st_mode;
3285+#endif
3286 }
3287
3288 /*
3289@@ -5682,7 +5689,7 @@
3290
3291 /*
3292 * Closes connection to gpm
3293- * returns non-zero if connection succesfully closed
3294+ * returns non-zero if connection successfully closed
3295 */
3296 static void
3297 gpm_close()
3298diff -Naur vim71.orig/src/os_unix.h vim71/src/os_unix.h
3299--- vim71.orig/src/os_unix.h 2007-05-07 12:35:05.000000000 -0700
3300+++ vim71/src/os_unix.h 2007-09-03 22:13:13.000000000 -0700
3301@@ -508,6 +508,9 @@
3302 #if !defined(S_ISFIFO) && defined(S_IFIFO)
3303 # define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
3304 #endif
3305+#if !defined(S_ISCHR) && defined(S_IFCHR)
3306+# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
3307+#endif
3308
3309 /* Note: Some systems need both string.h and strings.h (Savage). However,
3310 * some systems can't handle both, only use string.h in that case. */
3311diff -Naur vim71.orig/src/popupmnu.c vim71/src/popupmnu.c
3312--- vim71.orig/src/popupmnu.c 2007-03-24 13:07:39.000000000 -0700
3313+++ vim71/src/popupmnu.c 2007-09-03 22:14:24.000000000 -0700
3314@@ -75,7 +75,6 @@
3315
3316 row = curwin->w_cline_row + W_WINROW(curwin);
3317 height = curwin->w_cline_height;
3318- col = curwin->w_wcol + W_WINCOL(curwin) - curwin->w_leftcol;
3319
3320 if (firstwin->w_p_pvw)
3321 top_clear = firstwin->w_height;
3322@@ -167,6 +166,15 @@
3323 pum_base_width = max_width;
3324 pum_kind_width = kind_width;
3325
3326+ /* Calculate column */
3327+#ifdef FEAT_RIGHTLEFT
3328+ if (curwin->w_p_rl)
3329+ col = W_WINCOL(curwin) + W_WIDTH(curwin) - curwin->w_wcol -
3330+ curwin->w_leftcol - 1;
3331+ else
3332+#endif
3333+ col = W_WINCOL(curwin) + curwin->w_wcol - curwin->w_leftcol;
3334+
3335 /* if there are more items than room we need a scrollbar */
3336 if (pum_height < size)
3337 {
3338@@ -179,11 +187,23 @@
3339 if (def_width < max_width)
3340 def_width = max_width;
3341
3342- if (col < Columns - PUM_DEF_WIDTH || col < Columns - max_width)
3343+ if (((col < Columns - PUM_DEF_WIDTH || col < Columns - max_width)
3344+#ifdef FEAT_RIGHTLEFT
3345+ && !curwin->w_p_rl)
3346+ || (curwin->w_p_rl && (col > PUM_DEF_WIDTH || col > max_width)
3347+#endif
3348+ ))
3349 {
3350 /* align pum column with "col" */
3351 pum_col = col;
3352- pum_width = Columns - pum_col - pum_scrollbar;
3353+
3354+#ifdef FEAT_RIGHTLEFT
3355+ if (curwin->w_p_rl)
3356+ pum_width = pum_col - pum_scrollbar + 1;
3357+ else
3358+#endif
3359+ pum_width = Columns - pum_col - pum_scrollbar;
3360+
3361 if (pum_width > max_width + kind_width + extra_width + 1
3362 && pum_width > PUM_DEF_WIDTH)
3363 {
3364@@ -195,14 +215,24 @@
3365 else if (Columns < def_width)
3366 {
3367 /* not enough room, will use what we have */
3368- pum_col = 0;
3369+#ifdef FEAT_RIGHTLEFT
3370+ if (curwin->w_p_rl)
3371+ pum_col = Columns - 1;
3372+ else
3373+#endif
3374+ pum_col = 0;
3375 pum_width = Columns - 1;
3376 }
3377 else
3378 {
3379 if (max_width > PUM_DEF_WIDTH)
3380 max_width = PUM_DEF_WIDTH; /* truncate */
3381- pum_col = Columns - max_width;
3382+#ifdef FEAT_RIGHTLEFT
3383+ if (curwin->w_p_rl)
3384+ pum_col = max_width - 1;
3385+ else
3386+#endif
3387+ pum_col = Columns - max_width;
3388 pum_width = max_width - pum_scrollbar;
3389 }
3390
3391@@ -255,8 +285,16 @@
3392 attr = (idx == pum_selected) ? attr_select : attr_norm;
3393
3394 /* prepend a space if there is room */
3395- if (pum_col > 0)
3396- screen_putchar(' ', row, pum_col - 1, attr);
3397+#ifdef FEAT_RIGHTLEFT
3398+ if (curwin->w_p_rl)
3399+ {
3400+ if (pum_col < W_WINCOL(curwin) + W_WIDTH(curwin) - 1)
3401+ screen_putchar(' ', row, pum_col + 1, attr);
3402+ }
3403+ else
3404+#endif
3405+ if (pum_col > 0)
3406+ screen_putchar(' ', row, pum_col - 1, attr);
3407
3408 /* Display each entry, use two spaces for a Tab.
3409 * Do this 3 times: For the main text, kind and extra info */
3410@@ -282,26 +320,67 @@
3411 {
3412 /* Display the text that fits or comes before a Tab.
3413 * First convert it to printable characters. */
3414- char_u *st;
3415- int saved = *p;
3416+ char_u *st;
3417+ int saved = *p;
3418
3419 *p = NUL;
3420 st = transstr(s);
3421 *p = saved;
3422- if (st != NULL)
3423+#ifdef FEAT_RIGHTLEFT
3424+ if (curwin->w_p_rl)
3425 {
3426- screen_puts_len(st, (int)STRLEN(st), row, col,
3427+ if (st != NULL)
3428+ {
3429+ char_u *rt = reverse_text(st);
3430+ char_u *rt_saved = rt;
3431+ int len, j;
3432+
3433+ if (rt != NULL)
3434+ {
3435+ len = STRLEN(rt);
3436+ if (len > pum_width)
3437+ {
3438+ for (j = pum_width; j < len; ++j)
3439+ mb_ptr_adv(rt);
3440+ len = pum_width;
3441+ }
3442+ screen_puts_len(rt, len, row,
3443+ col - len + 1, attr);
3444+ vim_free(rt_saved);
3445+ }
3446+ vim_free(st);
3447+ }
3448+ col -= width;
3449+ }
3450+ else
3451+#endif
3452+ {
3453+ if (st != NULL)
3454+ {
3455+ screen_puts_len(st, (int)STRLEN(st), row, col,
3456 attr);
3457- vim_free(st);
3458+ vim_free(st);
3459+ }
3460+ col += width;
3461 }
3462- col += width;
3463
3464 if (*p != TAB)
3465 break;
3466
3467 /* Display two spaces for a Tab. */
3468- screen_puts_len((char_u *)" ", 2, row, col, attr);
3469- col += 2;
3470+#ifdef FEAT_RIGHTLEFT
3471+ if (curwin->w_p_rl)
3472+ {
3473+ screen_puts_len((char_u *)" ", 2, row, col - 1,
3474+ attr);
3475+ col -= 2;
3476+ }
3477+ else
3478+#endif
3479+ {
3480+ screen_puts_len((char_u *)" ", 2, row, col, attr);
3481+ col += 2;
3482+ }
3483 totwidth += 2;
3484 s = NULL; /* start text at next char */
3485 width = 0;
3486@@ -322,17 +401,44 @@
3487 && pum_array[idx].pum_extra == NULL)
3488 || pum_base_width + n >= pum_width)
3489 break;
3490- screen_fill(row, row + 1, col, pum_col + pum_base_width + n,
3491+#ifdef FEAT_RIGHTLEFT
3492+ if (curwin->w_p_rl)
3493+ {
3494+ screen_fill(row, row + 1, pum_col - pum_base_width - n + 1,
3495+ col + 1, ' ', ' ', attr);
3496+ col = pum_col - pum_base_width - n + 1;
3497+ }
3498+ else
3499+#endif
3500+ {
3501+ screen_fill(row, row + 1, col, pum_col + pum_base_width + n,
3502 ' ', ' ', attr);
3503- col = pum_col + pum_base_width + n;
3504+ col = pum_col + pum_base_width + n;
3505+ }
3506 totwidth = pum_base_width + n;
3507 }
3508
3509- screen_fill(row, row + 1, col, pum_col + pum_width, ' ', ' ', attr);
3510+#ifdef FEAT_RIGHTLEFT
3511+ if (curwin->w_p_rl)
3512+ screen_fill(row, row + 1, pum_col - pum_width + 1, col + 1, ' ',
3513+ ' ', attr);
3514+ else
3515+#endif
3516+ screen_fill(row, row + 1, col, pum_col + pum_width, ' ', ' ',
3517+ attr);
3518 if (pum_scrollbar > 0)
3519- screen_putchar(' ', row, pum_col + pum_width,
3520- i >= thumb_pos && i < thumb_pos + thumb_heigth
3521+ {
3522+#ifdef FEAT_RIGHTLEFT
3523+ if (curwin->w_p_rl)
3524+ screen_putchar(' ', row, pum_col - pum_width,
3525+ i >= thumb_pos && i < thumb_pos + thumb_heigth
3526 ? attr_thumb : attr_scroll);
3527+ else
3528+#endif
3529+ screen_putchar(' ', row, pum_col + pum_width,
3530+ i >= thumb_pos && i < thumb_pos + thumb_heigth
3531+ ? attr_thumb : attr_scroll);
3532+ }
3533
3534 ++row;
3535 }
3536@@ -466,7 +572,7 @@
3537 set_option_value((char_u *)"bh", 0L,
3538 (char_u *)"wipe", OPT_LOCAL);
3539 set_option_value((char_u *)"diff", 0L,
3540- (char_u *)"", OPT_LOCAL);
3541+ NULL, OPT_LOCAL);
3542 }
3543 }
3544 if (res == OK)
3545diff -Naur vim71.orig/src/proto/charset.pro vim71/src/proto/charset.pro
3546--- vim71.orig/src/proto/charset.pro 2007-05-12 03:39:01.000000000 -0700
3547+++ vim71/src/proto/charset.pro 2007-09-03 22:15:22.000000000 -0700
3548@@ -21,6 +21,7 @@
3549 int vim_iswordp __ARGS((char_u *p));
3550 int vim_iswordc_buf __ARGS((char_u *p, buf_T *buf));
3551 int vim_isfilec __ARGS((int c));
3552+int vim_isfilec_or_wc __ARGS((int c));
3553 int vim_isprintc __ARGS((int c));
3554 int vim_isprintc_strict __ARGS((int c));
3555 int lbr_chartabsize __ARGS((unsigned char *s, colnr_T col));
3556diff -Naur vim71.orig/src/proto/fileio.pro vim71/src/proto/fileio.pro
3557--- vim71.orig/src/proto/fileio.pro 2007-05-12 03:39:14.000000000 -0700
3558+++ vim71/src/proto/fileio.pro 2007-09-03 22:12:50.000000000 -0700
3559@@ -2,6 +2,7 @@
3560 void filemess __ARGS((buf_T *buf, char_u *name, char_u *s, int attr));
3561 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));
3562 int prep_exarg __ARGS((exarg_T *eap, buf_T *buf));
3563+int check_file_readonly __ARGS((char_u *fname, int perm));
3564 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));
3565 void msg_add_fname __ARGS((buf_T *buf, char_u *fname));
3566 void msg_add_lines __ARGS((int insert_space, long lnum, long nchars));
3567diff -Naur vim71.orig/src/proto/mbyte.pro vim71/src/proto/mbyte.pro
3568--- vim71.orig/src/proto/mbyte.pro 2007-05-12 03:39:38.000000000 -0700
3569+++ vim71/src/proto/mbyte.pro 2007-09-03 22:15:45.000000000 -0700
3570@@ -12,9 +12,9 @@
3571 int utf_ptr2cells __ARGS((char_u *p));
3572 int dbcs_ptr2cells __ARGS((char_u *p));
3573 int latin_char2cells __ARGS((int c));
3574-int latin_off2cells __ARGS((unsigned off));
3575-int dbcs_off2cells __ARGS((unsigned off));
3576-int utf_off2cells __ARGS((unsigned off));
3577+int latin_off2cells __ARGS((unsigned off, unsigned max_off));
3578+int dbcs_off2cells __ARGS((unsigned off, unsigned max_off));
3579+int utf_off2cells __ARGS((unsigned off, unsigned max_off));
3580 int latin_ptr2char __ARGS((char_u *p));
3581 int utf_ptr2char __ARGS((char_u *p));
3582 int mb_ptr2char_adv __ARGS((char_u **pp));
3583diff -Naur vim71.orig/src/proto/search.pro vim71/src/proto/search.pro
3584--- vim71.orig/src/proto/search.pro 2007-05-12 03:39:50.000000000 -0700
3585+++ vim71/src/proto/search.pro 2007-09-03 22:14:24.000000000 -0700
3586@@ -1,6 +1,7 @@
3587 /* search.c */
3588 int search_regcomp __ARGS((char_u *pat, int pat_save, int pat_use, int options, regmmatch_T *regmatch));
3589 char_u *get_search_pat __ARGS((void));
3590+char_u *reverse_text __ARGS((char_u *s));
3591 void save_search_patterns __ARGS((void));
3592 void restore_search_patterns __ARGS((void));
3593 void free_search_patterns __ARGS((void));
3594diff -Naur vim71.orig/src/proto/syntax.pro vim71/src/proto/syntax.pro
3595--- vim71.orig/src/proto/syntax.pro 2007-05-12 03:39:52.000000000 -0700
3596+++ vim71/src/proto/syntax.pro 2007-09-03 22:13:33.000000000 -0700
3597@@ -8,6 +8,8 @@
3598 void syntax_clear __ARGS((buf_T *buf));
3599 void ex_syntax __ARGS((exarg_T *eap));
3600 int syntax_present __ARGS((buf_T *buf));
3601+void reset_expand_highlight __ARGS((void));
3602+void set_context_in_echohl_cmd __ARGS((expand_T *xp, char_u *arg));
3603 void set_context_in_syntax_cmd __ARGS((expand_T *xp, char_u *arg));
3604 char_u *get_syntax_name __ARGS((expand_T *xp, int idx));
3605 int syn_get_id __ARGS((win_T *wp, long lnum, colnr_T col, int trans, int *spellp));
3606diff -Naur vim71.orig/src/proto/window.pro vim71/src/proto/window.pro
3607--- vim71.orig/src/proto/window.pro 2007-05-12 03:40:00.000000000 -0700
3608+++ vim71/src/proto/window.pro 2007-09-03 22:13:43.000000000 -0700
3609@@ -59,4 +59,8 @@
3610 int only_one_window __ARGS((void));
3611 void check_lnums __ARGS((int do_curwin));
3612 int win_hasvertsplit __ARGS((void));
3613+int match_add __ARGS((win_T *wp, char_u *grp, char_u *pat, int prio, int id));
3614+int match_delete __ARGS((win_T *wp, int id, int perr));
3615+void clear_matches __ARGS((win_T *wp));
3616+matchitem_T *get_match __ARGS((win_T *wp, int id));
3617 /* vim: set ft=c : */
3618diff -Naur vim71.orig/src/quickfix.c vim71/src/quickfix.c
3619--- vim71.orig/src/quickfix.c 2007-02-03 16:50:17.000000000 -0800
3620+++ vim71/src/quickfix.c 2007-09-03 22:12:48.000000000 -0700
3621@@ -2331,7 +2331,7 @@
3622 set_option_value((char_u *)"bt", 0L, (char_u *)"quickfix",
3623 OPT_LOCAL);
3624 set_option_value((char_u *)"bh", 0L, (char_u *)"wipe", OPT_LOCAL);
3625- set_option_value((char_u *)"diff", 0L, (char_u *)"", OPT_LOCAL);
3626+ set_option_value((char_u *)"diff", 0L, NULL, OPT_LOCAL);
3627 }
3628
3629 /* Only set the height when still in the same tab page and there is no
3630diff -Naur vim71.orig/src/regexp.c vim71/src/regexp.c
3631--- vim71.orig/src/regexp.c 2007-05-07 12:50:03.000000000 -0700
3632+++ vim71/src/regexp.c 2007-09-03 22:14:31.000000000 -0700
3633@@ -2220,7 +2220,7 @@
3634 break;
3635 case CLASS_LOWER:
3636 for (cu = 1; cu <= 255; cu++)
3637- if (islower(cu))
3638+ if (MB_ISLOWER(cu))
3639 regc(cu);
3640 break;
3641 case CLASS_PRINT:
3642@@ -2240,7 +2240,7 @@
3643 break;
3644 case CLASS_UPPER:
3645 for (cu = 1; cu <= 255; cu++)
3646- if (isupper(cu))
3647+ if (MB_ISUPPER(cu))
3648 regc(cu);
3649 break;
3650 case CLASS_XDIGIT:
3651@@ -3465,7 +3465,7 @@
3652 (enc_utf8 && utf_fold(prog->regstart) == utf_fold(c)))
3653 || (c < 255 && prog->regstart < 255 &&
3654 #endif
3655- TOLOWER_LOC(prog->regstart) == TOLOWER_LOC(c)))))
3656+ MB_TOLOWER(prog->regstart) == MB_TOLOWER(c)))))
3657 retval = regtry(prog, col);
3658 else
3659 retval = 0;
3660@@ -4200,7 +4200,7 @@
3661 #ifdef FEAT_MBYTE
3662 !enc_utf8 &&
3663 #endif
3664- TOLOWER_LOC(*opnd) != TOLOWER_LOC(*reginput))))
3665+ MB_TOLOWER(*opnd) != MB_TOLOWER(*reginput))))
3666 status = RA_NOMATCH;
3667 else if (*opnd == NUL)
3668 {
3669@@ -4733,10 +4733,10 @@
3670 rst.nextb = *OPERAND(next);
3671 if (ireg_ic)
3672 {
3673- if (isupper(rst.nextb))
3674- rst.nextb_ic = TOLOWER_LOC(rst.nextb);
3675+ if (MB_ISUPPER(rst.nextb))
3676+ rst.nextb_ic = MB_TOLOWER(rst.nextb);
3677 else
3678- rst.nextb_ic = TOUPPER_LOC(rst.nextb);
3679+ rst.nextb_ic = MB_TOUPPER(rst.nextb);
3680 }
3681 else
3682 rst.nextb_ic = rst.nextb;
3683@@ -5558,11 +5558,12 @@
3684 int cu, cl;
3685
3686 /* This doesn't do a multi-byte character, because a MULTIBYTECODE
3687- * would have been used for it. */
3688+ * would have been used for it. It does handle single-byte
3689+ * characters, such as latin1. */
3690 if (ireg_ic)
3691 {
3692- cu = TOUPPER_LOC(*opnd);
3693- cl = TOLOWER_LOC(*opnd);
3694+ cu = MB_TOUPPER(*opnd);
3695+ cl = MB_TOLOWER(*opnd);
3696 while (count < maxcount && (*scan == cu || *scan == cl))
3697 {
3698 count++;
3699@@ -6490,10 +6491,10 @@
3700 cc = utf_fold(c);
3701 else
3702 #endif
3703- if (isupper(c))
3704- cc = TOLOWER_LOC(c);
3705- else if (islower(c))
3706- cc = TOUPPER_LOC(c);
3707+ if (MB_ISUPPER(c))
3708+ cc = MB_TOLOWER(c);
3709+ else if (MB_ISLOWER(c))
3710+ cc = MB_TOUPPER(c);
3711 else
3712 return vim_strchr(s, c);
3713
3714@@ -6637,9 +6638,9 @@
3715 }
3716 }
3717 else if (magic)
3718- STRCPY(p, p + 1); /* remove '~' */
3719+ mch_memmove(p, p + 1, STRLEN(p)); /* remove '~' */
3720 else
3721- STRCPY(p, p + 2); /* remove '\~' */
3722+ mch_memmove(p, p + 2, STRLEN(p) - 1); /* remove '\~' */
3723 --p;
3724 }
3725 else
3726@@ -7014,7 +7015,14 @@
3727 #ifdef FEAT_MBYTE
3728 if (has_mbyte)
3729 {
3730- int l = mb_ptr2len(s) - 1;
3731+ int l;
3732+
3733+ /* Copy composing characters separately, one
3734+ * at a time. */
3735+ if (enc_utf8)
3736+ l = utf_ptr2len(s) - 1;
3737+ else
3738+ l = mb_ptr2len(s) - 1;
3739
3740 s += l;
3741 len -= l;
3742diff -Naur vim71.orig/src/screen.c vim71/src/screen.c
3743--- vim71.orig/src/screen.c 2007-05-07 12:27:53.000000000 -0700
3744+++ vim71/src/screen.c 2007-09-03 22:15:45.000000000 -0700
3745@@ -100,27 +100,7 @@
3746 static int screen_cur_row, screen_cur_col; /* last known cursor position */
3747
3748 #ifdef FEAT_SEARCH_EXTRA
3749-/*
3750- * Struct used for highlighting 'hlsearch' matches for the last use search
3751- * pattern or a ":match" item.
3752- * For 'hlsearch' there is one pattern for all windows. For ":match" there is
3753- * a different pattern for each window.
3754- */
3755-typedef struct
3756-{
3757- regmmatch_T rm; /* points to the regexp program; contains last found
3758- match (may continue in next line) */
3759- buf_T *buf; /* the buffer to search for a match */
3760- linenr_T lnum; /* the line to search for a match */
3761- int attr; /* attributes to be used for a match */
3762- int attr_cur; /* attributes currently active in win_line() */
3763- linenr_T first_lnum; /* first lnum to search for multi-line pat */
3764- colnr_T startcol; /* in win_line() points to char where HL starts */
3765- colnr_T endcol; /* in win_line() points to char where HL ends */
3766-} match_T;
3767-
3768 static match_T search_hl; /* used for 'hlsearch' highlight matching */
3769-static match_T match_hl[3]; /* used for ":match" highlight matching */
3770 #endif
3771
3772 #ifdef FEAT_FOLDING
3773@@ -155,6 +135,7 @@
3774 static void redraw_custum_statusline __ARGS((win_T *wp));
3775 #endif
3776 #ifdef FEAT_SEARCH_EXTRA
3777+#define SEARCH_HL_PRIORITY 0
3778 static void start_search_hl __ARGS((void));
3779 static void end_search_hl __ARGS((void));
3780 static void prepare_search_hl __ARGS((win_T *wp, linenr_T lnum));
3781@@ -350,6 +331,11 @@
3782 {
3783 if (type < must_redraw) /* use maximal type */
3784 type = must_redraw;
3785+
3786+ /* must_redraw is reset here, so that when we run into some weird
3787+ * reason to redraw while busy redrawing (e.g., asynchronous
3788+ * scrolling), or update_topline() in win_update() will cause a
3789+ * scroll, the screen will be redrawn later or in win_update(). */
3790 must_redraw = 0;
3791 }
3792
3793@@ -787,6 +773,7 @@
3794 w_topline got smaller a bit */
3795 #endif
3796 #ifdef FEAT_SEARCH_EXTRA
3797+ matchitem_T *cur; /* points to the match list */
3798 int top_to_mod = FALSE; /* redraw above mod_top */
3799 #endif
3800
3801@@ -848,18 +835,20 @@
3802 #endif
3803
3804 #ifdef FEAT_SEARCH_EXTRA
3805- /* Setup for ":match" and 'hlsearch' highlighting. Disable any previous
3806+ /* Setup for match and 'hlsearch' highlighting. Disable any previous
3807 * match */
3808- for (i = 0; i < 3; ++i)
3809+ cur = wp->w_match_head;
3810+ while (cur != NULL)
3811 {
3812- match_hl[i].rm = wp->w_match[i];
3813- if (wp->w_match_id[i] == 0)
3814- match_hl[i].attr = 0;
3815- else
3816- match_hl[i].attr = syn_id2attr(wp->w_match_id[i]);
3817- match_hl[i].buf = buf;
3818- match_hl[i].lnum = 0;
3819- match_hl[i].first_lnum = 0;
3820+ cur->hl.rm = cur->match;
3821+ if (cur->hlg_id == 0)
3822+ cur->hl.attr = 0;
3823+ else
3824+ cur->hl.attr = syn_id2attr(cur->hlg_id);
3825+ cur->hl.buf = buf;
3826+ cur->hl.lnum = 0;
3827+ cur->hl.first_lnum = 0;
3828+ cur = cur->next;
3829 }
3830 search_hl.buf = buf;
3831 search_hl.lnum = 0;
3832@@ -923,19 +912,25 @@
3833 * change in one line may make the Search highlighting in a
3834 * previous line invalid. Simple solution: redraw all visible
3835 * lines above the change.
3836- * Same for a ":match" pattern.
3837+ * Same for a match pattern.
3838 */
3839 if (search_hl.rm.regprog != NULL
3840 && re_multiline(search_hl.rm.regprog))
3841 top_to_mod = TRUE;
3842 else
3843- for (i = 0; i < 3; ++i)
3844- if (match_hl[i].rm.regprog != NULL
3845- && re_multiline(match_hl[i].rm.regprog))
3846+ {
3847+ cur = wp->w_match_head;
3848+ while (cur != NULL)
3849+ {
3850+ if (cur->match.regprog != NULL
3851+ && re_multiline(cur->match.regprog))
3852 {
3853 top_to_mod = TRUE;
3854 break;
3855 }
3856+ cur = cur->next;
3857+ }
3858+ }
3859 #endif
3860 }
3861 #ifdef FEAT_FOLDING
3862@@ -1029,6 +1024,13 @@
3863 type = VALID;
3864 }
3865
3866+ /* Trick: we want to avoid clearing the screen twice. screenclear() will
3867+ * set "screen_cleared" to TRUE. The special value MAYBE (which is still
3868+ * non-zero and thus not FALSE) will indicate that screenclear() was not
3869+ * called. */
3870+ if (screen_cleared)
3871+ screen_cleared = MAYBE;
3872+
3873 /*
3874 * If there are no changes on the screen that require a complete redraw,
3875 * handle three cases:
3876@@ -1230,7 +1232,11 @@
3877 mid_end = wp->w_height;
3878 if (lastwin == firstwin)
3879 {
3880- screenclear();
3881+ /* Clear the screen when it was not done by win_del_lines() or
3882+ * win_ins_lines() above, "screen_cleared" is FALSE or MAYBE
3883+ * then. */
3884+ if (screen_cleared != TRUE)
3885+ screenclear();
3886 #ifdef FEAT_WINDOWS
3887 /* The screen was cleared, redraw the tab pages line. */
3888 if (redraw_tabline)
3889@@ -1238,6 +1244,13 @@
3890 #endif
3891 }
3892 }
3893+
3894+ /* When win_del_lines() or win_ins_lines() caused the screen to be
3895+ * cleared (only happens for the first window) or when screenclear()
3896+ * was called directly above, "must_redraw" will have been set to
3897+ * NOT_VALID, need to reset it here to avoid redrawing twice. */
3898+ if (screen_cleared == TRUE)
3899+ must_redraw = 0;
3900 }
3901 else
3902 {
3903@@ -2542,7 +2555,7 @@
3904
3905 char_u extra[18]; /* "%ld" and 'fdc' must fit in here */
3906 int n_extra = 0; /* number of extra chars */
3907- char_u *p_extra = NULL; /* string of extra chars */
3908+ char_u *p_extra = NULL; /* string of extra chars, plus NUL */
3909 int c_extra = NUL; /* extra chars, all the same */
3910 int extra_attr = 0; /* attributes when n_extra != 0 */
3911 static char_u *at_end_str = (char_u *)""; /* used for p_extra when
3912@@ -2626,10 +2639,13 @@
3913 int line_attr = 0; /* atrribute for the whole line */
3914 #endif
3915 #ifdef FEAT_SEARCH_EXTRA
3916- match_T *shl; /* points to search_hl or match_hl */
3917-#endif
3918-#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_MBYTE)
3919- int i;
3920+ matchitem_T *cur; /* points to the match list */
3921+ match_T *shl; /* points to search_hl or a match */
3922+ int shl_flag; /* flag to indicate whether search_hl
3923+ has been processed or not */
3924+ int prevcol_hl_flag; /* flag to indicate whether prevcol
3925+ equals startcol of search_hl or one
3926+ of the matches */
3927 #endif
3928 #ifdef FEAT_ARABIC
3929 int prev_c = 0; /* previous Arabic character */
3930@@ -3074,12 +3090,20 @@
3931
3932 #ifdef FEAT_SEARCH_EXTRA
3933 /*
3934- * Handle highlighting the last used search pattern and ":match".
3935- * Do this for both search_hl and match_hl[3].
3936+ * Handle highlighting the last used search pattern and matches.
3937+ * Do this for both search_hl and the match list.
3938 */
3939- for (i = 3; i >= 0; --i)
3940+ cur = wp->w_match_head;
3941+ shl_flag = FALSE;
3942+ while (cur != NULL || shl_flag == FALSE)
3943 {
3944- shl = (i == 3) ? &search_hl : &match_hl[i];
3945+ if (shl_flag == FALSE)
3946+ {
3947+ shl = &search_hl;
3948+ shl_flag = TRUE;
3949+ }
3950+ else
3951+ shl = &cur->hl;
3952 shl->startcol = MAXCOL;
3953 shl->endcol = MAXCOL;
3954 shl->attr_cur = 0;
3955@@ -3122,6 +3146,8 @@
3956 area_highlighting = TRUE;
3957 }
3958 }
3959+ if (shl != &search_hl && cur != NULL)
3960+ cur = cur->next;
3961 }
3962 #endif
3963
3964@@ -3163,10 +3189,8 @@
3965 if (cmdwin_type != 0 && wp == curwin)
3966 {
3967 /* Draw the cmdline character. */
3968- *extra = cmdwin_type;
3969 n_extra = 1;
3970- p_extra = extra;
3971- c_extra = NUL;
3972+ c_extra = cmdwin_type;
3973 char_attr = hl_attr(HLF_AT);
3974 }
3975 }
3976@@ -3182,6 +3206,7 @@
3977 fill_foldcolumn(extra, wp, FALSE, lnum);
3978 n_extra = wp->w_p_fdc;
3979 p_extra = extra;
3980+ p_extra[n_extra] = NUL;
3981 c_extra = NUL;
3982 char_attr = hl_attr(HLF_FC);
3983 }
3984@@ -3388,13 +3413,24 @@
3985 * After end, check for start/end of next match.
3986 * When another match, have to check for start again.
3987 * Watch out for matching an empty string!
3988- * Do this first for search_hl, then for match_hl, so that
3989- * ":match" overrules 'hlsearch'.
3990+ * Do this for 'search_hl' and the match list (ordered by
3991+ * priority).
3992 */
3993 v = (long)(ptr - line);
3994- for (i = 3; i >= 0; --i)
3995- {
3996- shl = (i == 3) ? &search_hl : &match_hl[i];
3997+ cur = wp->w_match_head;
3998+ shl_flag = FALSE;
3999+ while (cur != NULL || shl_flag == FALSE)
4000+ {
4001+ if (shl_flag == FALSE
4002+ && ((cur != NULL
4003+ && cur->priority > SEARCH_HL_PRIORITY)
4004+ || cur == NULL))
4005+ {
4006+ shl = &search_hl;
4007+ shl_flag = TRUE;
4008+ }
4009+ else
4010+ shl = &cur->hl;
4011 while (shl->rm.regprog != NULL)
4012 {
4013 if (shl->startcol != MAXCOL
4014@@ -3442,26 +3478,43 @@
4015 }
4016 break;
4017 }
4018+ if (shl != &search_hl && cur != NULL)
4019+ cur = cur->next;
4020 }
4021
4022- /* ":match" highlighting overrules 'hlsearch' */
4023- for (i = 0; i <= 3; ++i)
4024- if (i == 3)
4025- search_attr = search_hl.attr_cur;
4026- else if (match_hl[i].attr_cur != 0)
4027+ /* Use attributes from match with highest priority among
4028+ * 'search_hl' and the match list. */
4029+ search_attr = search_hl.attr_cur;
4030+ cur = wp->w_match_head;
4031+ shl_flag = FALSE;
4032+ while (cur != NULL || shl_flag == FALSE)
4033+ {
4034+ if (shl_flag == FALSE
4035+ && ((cur != NULL
4036+ && cur->priority > SEARCH_HL_PRIORITY)
4037+ || cur == NULL))
4038 {
4039- search_attr = match_hl[i].attr_cur;
4040- break;
4041+ shl = &search_hl;
4042+ shl_flag = TRUE;
4043 }
4044+ else
4045+ shl = &cur->hl;
4046+ if (shl->attr_cur != 0)
4047+ search_attr = shl->attr_cur;
4048+ if (shl != &search_hl && cur != NULL)
4049+ cur = cur->next;
4050+ }
4051 }
4052 #endif
4053
4054 #ifdef FEAT_DIFF
4055 if (diff_hlf != (hlf_T)0)
4056 {
4057- if (diff_hlf == HLF_CHD && ptr - line >= change_start)
4058+ if (diff_hlf == HLF_CHD && ptr - line >= change_start
4059+ && n_extra == 0)
4060 diff_hlf = HLF_TXD; /* changed text */
4061- if (diff_hlf == HLF_TXD && ptr - line > change_end)
4062+ if (diff_hlf == HLF_TXD && ptr - line > change_end
4063+ && n_extra == 0)
4064 diff_hlf = HLF_CHD; /* changed line */
4065 line_attr = hl_attr(diff_hlf);
4066 }
4067@@ -3496,9 +3549,11 @@
4068 * Get the next character to put on the screen.
4069 */
4070 /*
4071- * The 'extra' array contains the extra stuff that is inserted to
4072- * represent special characters (non-printable stuff). When all
4073- * characters are the same, c_extra is used.
4074+ * The "p_extra" points to the extra stuff that is inserted to
4075+ * represent special characters (non-printable stuff) and other
4076+ * things. When all characters are the same, c_extra is used.
4077+ * "p_extra" must end in a NUL to avoid mb_ptr2len() reads past
4078+ * "p_extra[n_extra]".
4079 * For the '$' of the 'list' option, n_extra == 1, p_extra == "".
4080 */
4081 if (n_extra > 0)
4082@@ -3611,6 +3666,8 @@
4083 * Draw it as a space with a composing char. */
4084 if (utf_iscomposing(mb_c))
4085 {
4086+ int i;
4087+
4088 for (i = Screen_mco - 1; i > 0; --i)
4089 u8cc[i] = u8cc[i - 1];
4090 u8cc[0] = mb_c;
4091@@ -3752,10 +3809,8 @@
4092 * a '<' in the first column. */
4093 if (n_skip > 0 && mb_l > 1)
4094 {
4095- extra[0] = '<';
4096- p_extra = extra;
4097 n_extra = 1;
4098- c_extra = NUL;
4099+ c_extra = '<';
4100 c = ' ';
4101 if (area_attr == 0 && search_attr == 0)
4102 {
4103@@ -4254,14 +4309,29 @@
4104 * highlight match at end of line. If it's beyond the last
4105 * char on the screen, just overwrite that one (tricky!) Not
4106 * needed when a '$' was displayed for 'list'. */
4107+#ifdef FEAT_SEARCH_EXTRA
4108+ prevcol_hl_flag = FALSE;
4109+ if (prevcol == (long)search_hl.startcol)
4110+ prevcol_hl_flag = TRUE;
4111+ else
4112+ {
4113+ cur = wp->w_match_head;
4114+ while (cur != NULL)
4115+ {
4116+ if (prevcol == (long)cur->hl.startcol)
4117+ {
4118+ prevcol_hl_flag = TRUE;
4119+ break;
4120+ }
4121+ cur = cur->next;
4122+ }
4123+ }
4124+#endif
4125 if (lcs_eol == lcs_eol_one
4126 && ((area_attr != 0 && vcol == fromcol && c == NUL)
4127 #ifdef FEAT_SEARCH_EXTRA
4128 /* highlight 'hlsearch' match at end of line */
4129- || ((prevcol == (long)search_hl.startcol
4130- || prevcol == (long)match_hl[0].startcol
4131- || prevcol == (long)match_hl[1].startcol
4132- || prevcol == (long)match_hl[2].startcol)
4133+ || (prevcol_hl_flag == TRUE
4134 # if defined(LINE_ATTR)
4135 && did_line_attr <= 1
4136 # endif
4137@@ -4302,15 +4372,27 @@
4138 #ifdef FEAT_SEARCH_EXTRA
4139 if (area_attr == 0)
4140 {
4141- for (i = 0; i <= 3; ++i)
4142- {
4143- if (i == 3)
4144- char_attr = search_hl.attr;
4145- else if ((ptr - line) - 1 == (long)match_hl[i].startcol)
4146+ /* Use attributes from match with highest priority among
4147+ * 'search_hl' and the match list. */
4148+ char_attr = search_hl.attr;
4149+ cur = wp->w_match_head;
4150+ shl_flag = FALSE;
4151+ while (cur != NULL || shl_flag == FALSE)
4152+ {
4153+ if (shl_flag == FALSE
4154+ && ((cur != NULL
4155+ && cur->priority > SEARCH_HL_PRIORITY)
4156+ || cur == NULL))
4157 {
4158- char_attr = match_hl[i].attr;
4159- break;
4160+ shl = &search_hl;
4161+ shl_flag = TRUE;
4162 }
4163+ else
4164+ shl = &cur->hl;
4165+ if ((ptr - line) - 1 == (long)shl->startcol)
4166+ char_attr = shl->attr;
4167+ if (shl != &search_hl && cur != NULL)
4168+ cur = cur->next;
4169 }
4170 }
4171 #endif
4172@@ -4460,6 +4542,8 @@
4173 {
4174 if (mb_utf8)
4175 {
4176+ int i;
4177+
4178 ScreenLinesUC[off] = mb_c;
4179 if ((c & 0xff) == 0)
4180 ScreenLines[off] = 0x80; /* avoid storing zero */
4181@@ -4548,7 +4632,7 @@
4182
4183 /*
4184 * At end of screen line and there is more to come: Display the line
4185- * so far. If there is no more to display it is catched above.
4186+ * so far. If there is no more to display it is caught above.
4187 */
4188 if ((
4189 #ifdef FEAT_RIGHTLEFT
4190@@ -4625,9 +4709,13 @@
4191 #endif
4192 #ifdef FEAT_MBYTE
4193 && !(has_mbyte
4194- && ((*mb_off2cells)(LineOffset[screen_row]) == 2
4195+ && ((*mb_off2cells)(LineOffset[screen_row],
4196+ LineOffset[screen_row] + screen_Columns)
4197+ == 2
4198 || (*mb_off2cells)(LineOffset[screen_row - 1]
4199- + (int)Columns - 2) == 2))
4200+ + (int)Columns - 2,
4201+ LineOffset[screen_row] + screen_Columns)
4202+ == 2))
4203 #endif
4204 )
4205 {
4206@@ -4787,6 +4875,10 @@
4207 {
4208 unsigned off_from;
4209 unsigned off_to;
4210+#ifdef FEAT_MBYTE
4211+ unsigned max_off_from;
4212+ unsigned max_off_to;
4213+#endif
4214 int col = 0;
4215 #if defined(FEAT_GUI) || defined(UNIX) || defined(FEAT_VERTSPLIT)
4216 int hl;
4217@@ -4813,6 +4905,10 @@
4218
4219 off_from = (unsigned)(current_ScreenLine - ScreenLines);
4220 off_to = LineOffset[row] + coloff;
4221+#ifdef FEAT_MBYTE
4222+ max_off_from = off_from + screen_Columns;
4223+ max_off_to = LineOffset[row] + screen_Columns;
4224+#endif
4225
4226 #ifdef FEAT_RIGHTLEFT
4227 if (rlflag)
4228@@ -4847,7 +4943,7 @@
4229 {
4230 #ifdef FEAT_MBYTE
4231 if (has_mbyte && (col + 1 < endcol))
4232- char_cells = (*mb_off2cells)(off_from);
4233+ char_cells = (*mb_off2cells)(off_from, max_off_from);
4234 else
4235 char_cells = 1;
4236 #endif
4237@@ -4924,7 +5020,7 @@
4238 * ScreenLinesUC[] is sufficient. */
4239 if (char_cells == 1
4240 && col + 1 < endcol
4241- && (*mb_off2cells)(off_to) > 1)
4242+ && (*mb_off2cells)(off_to, max_off_to) > 1)
4243 {
4244 /* Writing a single-cell character over a double-cell
4245 * character: need to redraw the next cell. */
4246@@ -4933,8 +5029,8 @@
4247 }
4248 else if (char_cells == 2
4249 && col + 2 < endcol
4250- && (*mb_off2cells)(off_to) == 1
4251- && (*mb_off2cells)(off_to + 1) > 1)
4252+ && (*mb_off2cells)(off_to, max_off_to) == 1
4253+ && (*mb_off2cells)(off_to + 1, max_off_to) > 1)
4254 {
4255 /* Writing the second half of a double-cell character over
4256 * a double-cell character: need to redraw the second
4257@@ -4953,10 +5049,10 @@
4258 * char over the left halve of an existing one. */
4259 if (has_mbyte && col + char_cells == endcol
4260 && ((char_cells == 1
4261- && (*mb_off2cells)(off_to) > 1)
4262+ && (*mb_off2cells)(off_to, max_off_to) > 1)
4263 || (char_cells == 2
4264- && (*mb_off2cells)(off_to) == 1
4265- && (*mb_off2cells)(off_to + 1) > 1)))
4266+ && (*mb_off2cells)(off_to, max_off_to) == 1
4267+ && (*mb_off2cells)(off_to + 1, max_off_to) > 1)))
4268 clear_next = TRUE;
4269 #endif
4270
4271@@ -5096,10 +5192,11 @@
4272 /* find previous character by counting from first
4273 * column and get its width. */
4274 unsigned off = LineOffset[row];
4275+ unsigned max_off = LineOffset[row] + screen_Columns;
4276
4277 while (off < off_to)
4278 {
4279- prev_cells = (*mb_off2cells)(off);
4280+ prev_cells = (*mb_off2cells)(off, max_off);
4281 off += prev_cells;
4282 }
4283 }
4284@@ -5285,7 +5382,7 @@
4285 static int skip_status_match_char __ARGS((expand_T *xp, char_u *s));
4286
4287 /*
4288- * Get the lenght of an item as it will be shown in the status line.
4289+ * Get the length of an item as it will be shown in the status line.
4290 */
4291 static int
4292 status_match_len(xp, s)
4293@@ -5351,7 +5448,7 @@
4294 int row;
4295 char_u *buf;
4296 int len;
4297- int clen; /* lenght in screen cells */
4298+ int clen; /* length in screen cells */
4299 int fillchar;
4300 int attr;
4301 int i;
4302@@ -6103,6 +6200,7 @@
4303 char_u *ptr = text;
4304 int c;
4305 #ifdef FEAT_MBYTE
4306+ unsigned max_off;
4307 int mbyte_blen = 1;
4308 int mbyte_cells = 1;
4309 int u8c = 0;
4310@@ -6119,8 +6217,12 @@
4311 return;
4312
4313 off = LineOffset[row] + col;
4314- while (*ptr != NUL && col < screen_Columns
4315- && (len < 0 || (int)(ptr - text) < len))
4316+#ifdef FEAT_MBYTE
4317+ max_off = LineOffset[row] + screen_Columns;
4318+#endif
4319+ while (col < screen_Columns
4320+ && (len < 0 || (int)(ptr - text) < len)
4321+ && *ptr != NUL)
4322 {
4323 c = *ptr;
4324 #ifdef FEAT_MBYTE
4325@@ -6241,19 +6343,19 @@
4326 else if (has_mbyte
4327 && (len < 0 ? ptr[mbyte_blen] == NUL
4328 : ptr + mbyte_blen >= text + len)
4329- && ((mbyte_cells == 1 && (*mb_off2cells)(off) > 1)
4330+ && ((mbyte_cells == 1 && (*mb_off2cells)(off, max_off) > 1)
4331 || (mbyte_cells == 2
4332- && (*mb_off2cells)(off) == 1
4333- && (*mb_off2cells)(off + 1) > 1)))
4334+ && (*mb_off2cells)(off, max_off) == 1
4335+ && (*mb_off2cells)(off + 1, max_off) > 1)))
4336 clear_next_cell = TRUE;
4337
4338 /* Make sure we never leave a second byte of a double-byte behind,
4339 * it confuses mb_off2cells(). */
4340 if (enc_dbcs
4341- && ((mbyte_cells == 1 && (*mb_off2cells)(off) > 1)
4342+ && ((mbyte_cells == 1 && (*mb_off2cells)(off, max_off) > 1)
4343 || (mbyte_cells == 2
4344- && (*mb_off2cells)(off) == 1
4345- && (*mb_off2cells)(off + 1) > 1)))
4346+ && (*mb_off2cells)(off, max_off) == 1
4347+ && (*mb_off2cells)(off + 1, max_off) > 1)))
4348 ScreenLines[off + mbyte_blen] = 0;
4349 #endif
4350 ScreenLines[off] = c;
4351@@ -6318,7 +6420,7 @@
4352
4353 #ifdef FEAT_SEARCH_EXTRA
4354 /*
4355- * Prepare for 'searchhl' highlighting.
4356+ * Prepare for 'hlsearch' highlighting.
4357 */
4358 static void
4359 start_search_hl()
4360@@ -6331,7 +6433,7 @@
4361 }
4362
4363 /*
4364- * Clean up for 'searchhl' highlighting.
4365+ * Clean up for 'hlsearch' highlighting.
4366 */
4367 static void
4368 end_search_hl()
4369@@ -6351,18 +6453,28 @@
4370 win_T *wp;
4371 linenr_T lnum;
4372 {
4373- match_T *shl; /* points to search_hl or match_hl */
4374+ matchitem_T *cur; /* points to the match list */
4375+ match_T *shl; /* points to search_hl or a match */
4376+ int shl_flag; /* flag to indicate whether search_hl
4377+ has been processed or not */
4378 int n;
4379- int i;
4380
4381 /*
4382 * When using a multi-line pattern, start searching at the top
4383 * of the window or just after a closed fold.
4384- * Do this both for search_hl and match_hl[3].
4385+ * Do this both for search_hl and the match list.
4386 */
4387- for (i = 3; i >= 0; --i)
4388+ cur = wp->w_match_head;
4389+ shl_flag = FALSE;
4390+ while (cur != NULL || shl_flag == FALSE)
4391 {
4392- shl = (i == 3) ? &search_hl : &match_hl[i];
4393+ if (shl_flag == FALSE)
4394+ {
4395+ shl = &search_hl;
4396+ shl_flag = TRUE;
4397+ }
4398+ else
4399+ shl = &cur->hl;
4400 if (shl->rm.regprog != NULL
4401 && shl->lnum == 0
4402 && re_multiline(shl->rm.regprog))
4403@@ -6397,11 +6509,13 @@
4404 }
4405 }
4406 }
4407+ if (shl != &search_hl && cur != NULL)
4408+ cur = cur->next;
4409 }
4410 }
4411
4412 /*
4413- * Search for a next 'searchl' or ":match" match.
4414+ * Search for a next 'hlsearch' or match.
4415 * Uses shl->buf.
4416 * Sets shl->lnum and shl->rm contents.
4417 * Note: Assumes a previous match is always before "lnum", unless
4418@@ -6411,7 +6525,7 @@
4419 static void
4420 next_search_hl(win, shl, lnum, mincol)
4421 win_T *win;
4422- match_T *shl; /* points to search_hl or match_hl */
4423+ match_T *shl; /* points to search_hl or a match */
4424 linenr_T lnum;
4425 colnr_T mincol; /* minimal column for a match */
4426 {
4427@@ -6479,7 +6593,7 @@
4428 /* Error while handling regexp: stop using this regexp. */
4429 if (shl == &search_hl)
4430 {
4431- /* don't free the regprog in match_hl[], it's a copy */
4432+ /* don't free regprog in the match list, it's a copy */
4433 vim_free(shl->rm.regprog);
4434 no_hlsearch = TRUE;
4435 }
4436@@ -6827,6 +6941,9 @@
4437 {
4438 int r, c;
4439 int off;
4440+#ifdef FEAT_MBYTE
4441+ int max_off;
4442+#endif
4443
4444 /* Can't use ScreenLines unless initialized */
4445 if (ScreenLines == NULL)
4446@@ -6837,10 +6954,13 @@
4447 for (r = row; r < row + height; ++r)
4448 {
4449 off = LineOffset[r];
4450+#ifdef FEAT_MBYTE
4451+ max_off = off + screen_Columns;
4452+#endif
4453 for (c = col; c < col + width; ++c)
4454 {
4455 #ifdef FEAT_MBYTE
4456- if (enc_dbcs != 0 && dbcs_off2cells(off + c) > 1)
4457+ if (enc_dbcs != 0 && dbcs_off2cells(off + c, max_off) > 1)
4458 {
4459 screen_char_2(off + c, r, c);
4460 ++c;
4461@@ -6850,7 +6970,7 @@
4462 {
4463 screen_char(off + c, r, c);
4464 #ifdef FEAT_MBYTE
4465- if (utf_off2cells(off + c) > 1)
4466+ if (utf_off2cells(off + c, max_off) > 1)
4467 ++c;
4468 #endif
4469 }
4470diff -Naur vim71.orig/src/search.c vim71/src/search.c
4471--- vim71.orig/src/search.c 2007-05-07 12:42:02.000000000 -0700
4472+++ vim71/src/search.c 2007-09-03 22:14:24.000000000 -0700
4473@@ -101,7 +101,6 @@
4474 static char_u *mr_pattern = NULL; /* pattern used by search_regcomp() */
4475 #ifdef FEAT_RIGHTLEFT
4476 static int mr_pattern_alloced = FALSE; /* mr_pattern was allocated */
4477-static char_u *reverse_text __ARGS((char_u *s));
4478 #endif
4479
4480 #ifdef FEAT_FIND_ID
4481@@ -228,12 +227,12 @@
4482 return mr_pattern;
4483 }
4484
4485-#ifdef FEAT_RIGHTLEFT
4486+#if defined(FEAT_RIGHTLEFT) || defined(PROTO)
4487 /*
4488 * Reverse text into allocated memory.
4489 * Returns the allocated string, NULL when out of memory.
4490 */
4491- static char_u *
4492+ char_u *
4493 reverse_text(s)
4494 char_u *s;
4495 {
4496@@ -573,8 +572,12 @@
4497 /*
4498 * Start searching in current line, unless searching backwards and
4499 * we're in column 0.
4500+ * If we are searching backwards, in column 0, and not including the
4501+ * current position, gain some efficiency by skipping back a line.
4502+ * Otherwise begin the search in the current line.
4503 */
4504- if (dir == BACKWARD && start_pos.col == 0)
4505+ if (dir == BACKWARD && start_pos.col == 0
4506+ && (options & SEARCH_START) == 0)
4507 {
4508 lnum = pos->lnum - 1;
4509 at_first_line = FALSE;
4510@@ -1894,7 +1897,7 @@
4511 }
4512
4513 #ifdef FEAT_RIGHTLEFT
4514- /* This is just guessing: when 'rightleft' is set, search for a maching
4515+ /* This is just guessing: when 'rightleft' is set, search for a matching
4516 * paren/brace in the other direction. */
4517 if (curwin->w_p_rl && vim_strchr((char_u *)"()[]{}<>", initc) != NULL)
4518 backwards = !backwards;
4519@@ -2124,6 +2127,9 @@
4520 else if (!backwards)
4521 inquote = TRUE;
4522 }
4523+
4524+ /* ml_get() only keeps one line, need to get linep again */
4525+ linep = ml_get(pos.lnum);
4526 }
4527 }
4528 }
4529@@ -2795,7 +2801,7 @@
4530 i = inc_cursor();
4531 if (i == -1 || (i >= 1 && last_line)) /* started at last char in file */
4532 return FAIL;
4533- if (i == 1 && eol && count == 0) /* started at last char in line */
4534+ if (i >= 1 && eol && count == 0) /* started at last char in line */
4535 return OK;
4536
4537 /*
4538@@ -3600,13 +3606,16 @@
4539 {
4540 oap->start = start_pos;
4541 oap->motion_type = MCHAR;
4542+ oap->inclusive = FALSE;
4543 if (sol)
4544- {
4545 incl(&curwin->w_cursor);
4546- oap->inclusive = FALSE;
4547- }
4548- else
4549+ else if (lt(start_pos, curwin->w_cursor))
4550+ /* Include the character under the cursor. */
4551 oap->inclusive = TRUE;
4552+ else
4553+ /* End is before the start (no text in between <>, [], etc.): don't
4554+ * operate on any text. */
4555+ curwin->w_cursor = start_pos;
4556 }
4557
4558 return OK;
4559@@ -3734,7 +3743,7 @@
4560
4561 if (in_html_tag(FALSE))
4562 {
4563- /* cursor on start tag, move to just after it */
4564+ /* cursor on start tag, move to its '>' */
4565 while (*ml_get_cursor() != '>')
4566 if (inc_cursor() < 0)
4567 break;
4568@@ -3838,7 +3847,7 @@
4569 /* Exclude the start tag. */
4570 curwin->w_cursor = start_pos;
4571 while (inc_cursor() >= 0)
4572- if (*ml_get_cursor() == '>' && lt(curwin->w_cursor, end_pos))
4573+ if (*ml_get_cursor() == '>')
4574 {
4575 inc_cursor();
4576 start_pos = curwin->w_cursor;
4577@@ -3860,7 +3869,11 @@
4578 #ifdef FEAT_VISUAL
4579 if (VIsual_active)
4580 {
4581- if (*p_sel == 'e')
4582+ /* If the end is before the start there is no text between tags, select
4583+ * the char under the cursor. */
4584+ if (lt(end_pos, start_pos))
4585+ curwin->w_cursor = start_pos;
4586+ else if (*p_sel == 'e')
4587 ++curwin->w_cursor.col;
4588 VIsual = start_pos;
4589 VIsual_mode = 'v';
4590@@ -3872,7 +3885,15 @@
4591 {
4592 oap->start = start_pos;
4593 oap->motion_type = MCHAR;
4594- oap->inclusive = TRUE;
4595+ if (lt(end_pos, start_pos))
4596+ {
4597+ /* End is before the start: there is no text between tags; operate
4598+ * on an empty area. */
4599+ curwin->w_cursor = start_pos;
4600+ oap->inclusive = FALSE;
4601+ }
4602+ else
4603+ oap->inclusive = TRUE;
4604 }
4605 retval = OK;
4606
4607diff -Naur vim71.orig/src/spell.c vim71/src/spell.c
4608--- vim71.orig/src/spell.c 2007-05-07 12:48:38.000000000 -0700
4609+++ vim71/src/spell.c 2007-09-03 22:14:08.000000000 -0700
4610@@ -7829,7 +7829,7 @@
4611 # if (_MSC_VER <= 1200)
4612 /* This line is required for VC6 without the service pack. Also see the
4613 * matching #pragma below. */
4614-/* # pragma optimize("", off) */
4615+ # pragma optimize("", off)
4616 # endif
4617 #endif
4618
4619@@ -7859,7 +7859,7 @@
4620
4621 #ifdef _MSC_VER
4622 # if (_MSC_VER <= 1200)
4623-/* # pragma optimize("", on) */
4624+ # pragma optimize("", on)
4625 # endif
4626 #endif
4627
4628@@ -12182,7 +12182,9 @@
4629 {
4630 n = mb_cptr2len(p);
4631 c = mb_ptr2char(p);
4632- if (!soundfold && !spell_iswordp(p + n, curbuf))
4633+ if (p[n] == NUL)
4634+ c2 = NUL;
4635+ else if (!soundfold && !spell_iswordp(p + n, curbuf))
4636 c2 = c; /* don't swap non-word char */
4637 else
4638 c2 = mb_ptr2char(p + n);
4639@@ -12190,12 +12192,21 @@
4640 else
4641 #endif
4642 {
4643- if (!soundfold && !spell_iswordp(p + 1, curbuf))
4644+ if (p[1] == NUL)
4645+ c2 = NUL;
4646+ else if (!soundfold && !spell_iswordp(p + 1, curbuf))
4647 c2 = c; /* don't swap non-word char */
4648 else
4649 c2 = p[1];
4650 }
4651
4652+ /* When the second character is NUL we can't swap. */
4653+ if (c2 == NUL)
4654+ {
4655+ sp->ts_state = STATE_REP_INI;
4656+ break;
4657+ }
4658+
4659 /* When characters are identical, swap won't do anything.
4660 * Also get here if the second char is not a word character. */
4661 if (c == c2)
4662diff -Naur vim71.orig/src/structs.h vim71/src/structs.h
4663--- vim71.orig/src/structs.h 2007-05-07 12:50:49.000000000 -0700
4664+++ vim71/src/structs.h 2007-09-03 22:14:43.000000000 -0700
4665@@ -1453,6 +1453,7 @@
4666 #ifdef FEAT_MBYTE
4667 char_u *b_start_fenc; /* 'fileencoding' when edit started or NULL */
4668 int b_bad_char; /* "++bad=" argument when edit started or 0 */
4669+ int b_start_bomb; /* 'bomb' when it was read */
4670 #endif
4671
4672 #ifdef FEAT_EVAL
4673@@ -1694,6 +1695,41 @@
4674 #define FR_COL 2 /* frame with a column of windows */
4675
4676 /*
4677+ * Struct used for highlighting 'hlsearch' matches, matches defined by
4678+ * ":match" and matches defined by match functions.
4679+ * For 'hlsearch' there is one pattern for all windows. For ":match" and the
4680+ * match functions there is a different pattern for each window.
4681+ */
4682+typedef struct
4683+{
4684+ regmmatch_T rm; /* points to the regexp program; contains last found
4685+ match (may continue in next line) */
4686+ buf_T *buf; /* the buffer to search for a match */
4687+ linenr_T lnum; /* the line to search for a match */
4688+ int attr; /* attributes to be used for a match */
4689+ int attr_cur; /* attributes currently active in win_line() */
4690+ linenr_T first_lnum; /* first lnum to search for multi-line pat */
4691+ colnr_T startcol; /* in win_line() points to char where HL starts */
4692+ colnr_T endcol; /* in win_line() points to char where HL ends */
4693+} match_T;
4694+
4695+/*
4696+ * matchitem_T provides a linked list for storing match items for ":match" and
4697+ * the match functions.
4698+ */
4699+typedef struct matchitem matchitem_T;
4700+struct matchitem
4701+{
4702+ matchitem_T *next;
4703+ int id; /* match ID */
4704+ int priority; /* match priority */
4705+ char_u *pattern; /* pattern to highlight */
4706+ int hlg_id; /* highlight group ID */
4707+ regmmatch_T match; /* regexp program for pattern */
4708+ match_T hl; /* struct for doing the actual highlighting */
4709+};
4710+
4711+/*
4712 * Structure which contains all information that belongs to a window
4713 *
4714 * All row numbers are relative to the start of the window, except w_winrow.
4715@@ -1934,9 +1970,8 @@
4716 #endif
4717
4718 #ifdef FEAT_SEARCH_EXTRA
4719- regmmatch_T w_match[3]; /* regexp programs for ":match" */
4720- char_u *(w_match_pat[3]); /* patterns for ":match" */
4721- int w_match_id[3]; /* highlight IDs for ":match" */
4722+ matchitem_T *w_match_head; /* head of match list */
4723+ int w_next_match_id; /* next match ID */
4724 #endif
4725
4726 /*
4727diff -Naur vim71.orig/src/syntax.c vim71/src/syntax.c
4728--- vim71.orig/src/syntax.c 2007-05-07 12:42:55.000000000 -0700
4729+++ vim71/src/syntax.c 2007-09-03 22:15:47.000000000 -0700
4730@@ -66,8 +66,10 @@
4731 #define HL_TABLE() ((struct hl_group *)((highlight_ga.ga_data)))
4732
4733 #ifdef FEAT_CMDL_COMPL
4734-static int include_default = FALSE; /* include "default" for expansion */
4735-static int include_link = FALSE; /* include "link" for expansion */
4736+/* Flags to indicate an additional string for highlight name completion. */
4737+static int include_none = 0; /* when 1 include "None" */
4738+static int include_default = 0; /* when 1 include "default" */
4739+static int include_link = 0; /* when 2 include "link" and "clear" */
4740 #endif
4741
4742 /*
4743@@ -277,7 +279,8 @@
4744 */
4745 typedef struct state_item
4746 {
4747- int si_idx; /* index of syntax pattern */
4748+ int si_idx; /* index of syntax pattern or
4749+ KEYWORD_IDX */
4750 int si_id; /* highlight group ID for keywords */
4751 int si_trans_id; /* idem, transparancy removed */
4752 int si_m_lnum; /* lnum of the match */
4753@@ -835,9 +838,18 @@
4754 current_lnum = end_lnum;
4755 break;
4756 }
4757- spp = &(SYN_ITEMS(syn_buf)[cur_si->si_idx]);
4758- found_flags = spp->sp_flags;
4759- found_match_idx = spp->sp_sync_idx;
4760+ if (cur_si->si_idx < 0)
4761+ {
4762+ /* Cannot happen? */
4763+ found_flags = 0;
4764+ found_match_idx = KEYWORD_IDX;
4765+ }
4766+ else
4767+ {
4768+ spp = &(SYN_ITEMS(syn_buf)[cur_si->si_idx]);
4769+ found_flags = spp->sp_flags;
4770+ found_match_idx = spp->sp_sync_idx;
4771+ }
4772 found_current_lnum = current_lnum;
4773 found_current_col = current_col;
4774 found_m_endpos = cur_si->si_m_endpos;
4775@@ -1725,6 +1737,13 @@
4776 {
4777 int attr = 0;
4778
4779+ if (can_spell != NULL)
4780+ /* Default: Only do spelling when there is no @Spell cluster or when
4781+ * ":syn spell toplevel" was used. */
4782+ *can_spell = syn_buf->b_syn_spell == SYNSPL_DEFAULT
4783+ ? (syn_buf->b_spell_cluster_id == 0)
4784+ : (syn_buf->b_syn_spell == SYNSPL_TOP);
4785+
4786 /* check for out of memory situation */
4787 if (syn_buf->b_sst_array == NULL)
4788 return 0;
4789@@ -2524,6 +2543,10 @@
4790 stateitem_T *sip = &CUR_STATE(idx);
4791 synpat_T *spp;
4792
4793+ /* This should not happen... */
4794+ if (sip->si_idx < 0)
4795+ return;
4796+
4797 spp = &(SYN_ITEMS(syn_buf)[sip->si_idx]);
4798 if (sip->si_flags & HL_MATCH)
4799 sip->si_id = spp->sp_syn_match_id;
4800@@ -2639,6 +2662,10 @@
4801 lpos_T end_endpos;
4802 int end_idx;
4803
4804+ /* return quickly for a keyword */
4805+ if (sip->si_idx < 0)
4806+ return;
4807+
4808 /* Don't update when it's already done. Can be a match of an end pattern
4809 * that started in a previous line. Watch out: can also be a "keepend"
4810 * from a containing item. */
4811@@ -2751,6 +2778,10 @@
4812 char_u *line;
4813 int had_match = FALSE;
4814
4815+ /* just in case we are invoked for a keyword */
4816+ if (idx < 0)
4817+ return;
4818+
4819 /*
4820 * Check for being called with a START pattern.
4821 * Can happen with a match that continues to the next line, because it
4822@@ -4460,8 +4491,8 @@
4823 current_syn_inc_tag = ++running_syn_inc_tag;
4824 prev_toplvl_grp = curbuf->b_syn_topgrp;
4825 curbuf->b_syn_topgrp = sgl_id;
4826- if (source ? do_source(eap->arg, FALSE, FALSE) == FAIL
4827- : source_runtime(eap->arg, DOSO_NONE) == FAIL)
4828+ if (source ? do_source(eap->arg, FALSE, DOSO_NONE) == FAIL
4829+ : source_runtime(eap->arg, TRUE) == FAIL)
4830 EMSG2(_(e_notopen), eap->arg);
4831 curbuf->b_syn_topgrp = prev_toplvl_grp;
4832 current_syn_inc_tag = prev_syn_inc_tag;
4833@@ -5956,8 +5987,8 @@
4834 {
4835 return (buf->b_syn_patterns.ga_len != 0
4836 || buf->b_syn_clusters.ga_len != 0
4837- || curbuf->b_keywtab.ht_used > 0
4838- || curbuf->b_keywtab_ic.ht_used > 0);
4839+ || buf->b_keywtab.ht_used > 0
4840+ || buf->b_keywtab_ic.ht_used > 0);
4841 }
4842
4843 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
4844@@ -5968,6 +5999,29 @@
4845 EXP_CASE /* expand ":syn case" arguments */
4846 } expand_what;
4847
4848+/*
4849+ * Reset include_link, include_default, include_none to 0.
4850+ * Called when we are done expanding.
4851+ */
4852+ void
4853+reset_expand_highlight()
4854+{
4855+ include_link = include_default = include_none = 0;
4856+}
4857+
4858+/*
4859+ * Handle command line completion for :match and :echohl command: Add "None"
4860+ * as highlight group.
4861+ */
4862+ void
4863+set_context_in_echohl_cmd(xp, arg)
4864+ expand_T *xp;
4865+ char_u *arg;
4866+{
4867+ xp->xp_context = EXPAND_HIGHLIGHT;
4868+ xp->xp_pattern = arg;
4869+ include_none = 1;
4870+}
4871
4872 /*
4873 * Handle command line completion for :syntax command.
4874@@ -5983,8 +6037,8 @@
4875 xp->xp_context = EXPAND_SYNTAX;
4876 expand_what = EXP_SUBCMD;
4877 xp->xp_pattern = arg;
4878- include_link = FALSE;
4879- include_default = FALSE;
4880+ include_link = 0;
4881+ include_default = 0;
4882
4883 /* (part of) subcommand already typed */
4884 if (*arg != NUL)
4885@@ -8479,7 +8533,7 @@
4886 syn_id2name(id)
4887 int id;
4888 {
4889- if (id <= 0 || id >= highlight_ga.ga_len)
4890+ if (id <= 0 || id > highlight_ga.ga_len)
4891 return (char_u *)"";
4892 return HL_TABLE()[id - 1].sg_name;
4893 }
4894@@ -8949,7 +9003,7 @@
4895 return OK;
4896 }
4897
4898-#ifdef FEAT_CMDL_COMPL
4899+#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
4900
4901 static void highlight_list __ARGS((void));
4902 static void highlight_list_two __ARGS((int cnt, int attr));
4903@@ -8967,8 +9021,8 @@
4904 /* Default: expand group names */
4905 xp->xp_context = EXPAND_HIGHLIGHT;
4906 xp->xp_pattern = arg;
4907- include_link = TRUE;
4908- include_default = TRUE;
4909+ include_link = 2;
4910+ include_default = 1;
4911
4912 /* (part of) subcommand already typed */
4913 if (*arg != NUL)
4914@@ -8976,7 +9030,7 @@
4915 p = skiptowhite(arg);
4916 if (*p != NUL) /* past "default" or group name */
4917 {
4918- include_default = FALSE;
4919+ include_default = 0;
4920 if (STRNCMP("default", arg, p - arg) == 0)
4921 {
4922 arg = skipwhite(p);
4923@@ -8985,7 +9039,7 @@
4924 }
4925 if (*p != NUL) /* past group name */
4926 {
4927- include_link = FALSE;
4928+ include_link = 0;
4929 if (arg[1] == 'i' && arg[0] == 'N')
4930 highlight_list();
4931 if (STRNCMP("link", arg, p - arg) == 0
4932@@ -9045,31 +9099,25 @@
4933 expand_T *xp;
4934 int idx;
4935 {
4936- if (idx == highlight_ga.ga_len
4937 #ifdef FEAT_CMDL_COMPL
4938- && include_link
4939-#endif
4940- )
4941+ if (idx == highlight_ga.ga_len && include_none != 0)
4942+ return (char_u *)"none";
4943+ if (idx == highlight_ga.ga_len + include_none && include_default != 0)
4944+ return (char_u *)"default";
4945+ if (idx == highlight_ga.ga_len + include_none + include_default
4946+ && include_link != 0)
4947 return (char_u *)"link";
4948- if (idx == highlight_ga.ga_len + 1
4949-#ifdef FEAT_CMDL_COMPL
4950- && include_link
4951-#endif
4952- )
4953+ if (idx == highlight_ga.ga_len + include_none + include_default + 1
4954+ && include_link != 0)
4955 return (char_u *)"clear";
4956- if (idx == highlight_ga.ga_len + 2
4957-#ifdef FEAT_CMDL_COMPL
4958- && include_default
4959 #endif
4960- )
4961- return (char_u *)"default";
4962 if (idx < 0 || idx >= highlight_ga.ga_len)
4963 return NULL;
4964 return HL_TABLE()[idx].sg_name;
4965 }
4966 #endif
4967
4968-#ifdef FEAT_GUI
4969+#if defined(FEAT_GUI) || defined(PROTO)
4970 /*
4971 * Free all the highlight group fonts.
4972 * Used when quitting for systems which need it.
4973diff -Naur vim71.orig/src/termlib.c vim71/src/termlib.c
4974--- vim71.orig/src/termlib.c 2007-05-07 12:39:49.000000000 -0700
4975+++ vim71/src/termlib.c 2007-09-03 22:14:17.000000000 -0700
4976@@ -191,7 +191,7 @@
4977 lbuf[0] == '\t' &&
4978 lbuf[1] == ':')
4979 {
4980- strcpy(lbuf, lbuf+2);
4981+ mch_memmove(lbuf, lbuf + 2, strlen(lbuf + 2) + 1);
4982 llen -= 2;
4983 }
4984 if (lbuf[llen-2] == '\\') /* and continuations */
4985diff -Naur vim71.orig/src/testdir/Makefile vim71/src/testdir/Makefile
4986--- vim71.orig/src/testdir/Makefile 2006-04-30 04:08:01.000000000 -0700
4987+++ vim71/src/testdir/Makefile 2007-09-03 22:14:54.000000000 -0700
4988@@ -1,9 +1,13 @@
4989 #
4990-# Makefile to run al tests for Vim
4991+# Makefile to run all tests for Vim
4992 #
4993
4994 VIMPROG = ../vim
4995
4996+# Uncomment this line for using valgrind.
4997+# The output goes into a file "valgrind.$PID" (sorry, no test number).
4998+# VALGRIND = valgrind --tool=memcheck --num-callers=15 --logfile=valgrind
4999+
5000 SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \
5001 test7.out test8.out test9.out test10.out test11.out \
5002 test12.out test13.out test14.out test15.out test17.out \
5003@@ -15,7 +19,8 @@
5004 test43.out test44.out test45.out test46.out test47.out \
5005 test48.out test49.out test51.out test52.out test53.out \
5006 test54.out test55.out test56.out test57.out test58.out \
5007- test59.out test60.out test61.out test62.out
5008+ test59.out test60.out test61.out test62.out test63.out \
5009+ test64.out
5010
5011 SCRIPTS_GUI = test16.out
5012
5013@@ -38,7 +43,7 @@
5014
5015 test1.out: test1.in
5016 -rm -f $*.failed tiny.vim small.vim mbyte.vim test.ok X* viminfo
5017- $(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
5018+ $(VALGRIND) $(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
5019 @/bin/sh -c "if diff test.out $*.ok; \
5020 then mv -f test.out $*.out; \
5021 else echo; \
5022@@ -51,7 +56,7 @@
5023 cp $*.ok test.ok
5024 # Sleep a moment to avoid that the xterm title is messed up
5025 @-sleep .2
5026- -$(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
5027+ -$(VALGRIND) $(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
5028 @/bin/sh -c "if test -f test.out; then\
5029 if diff test.out $*.ok; \
5030 then mv -f test.out $*.out; \
5031diff -Naur vim71.orig/src/testdir/test63.in vim71/src/testdir/test63.in
5032--- vim71.orig/src/testdir/test63.in 1969-12-31 16:00:00.000000000 -0800
5033+++ vim71/src/testdir/test63.in 2007-09-03 22:13:43.000000000 -0700
5034@@ -0,0 +1,157 @@
5035+Test for ":match", ":2match", ":3match", "clearmatches()", "getmatches()",
5036+"matchadd()", "matcharg()", "matchdelete()", and "setmatches()".
5037+
5038+STARTTEST
5039+:so small.vim
5040+:" --- Check that "matcharg()" returns the correct group and pattern if a match
5041+:" --- is defined.
5042+:let @r = "*** Test 1: "
5043+:highlight MyGroup1 ctermbg=red
5044+:highlight MyGroup2 ctermbg=green
5045+:highlight MyGroup3 ctermbg=blue
5046+:match MyGroup1 /TODO/
5047+:2match MyGroup2 /FIXME/
5048+:3match MyGroup3 /XXX/
5049+:if matcharg(1) == ['MyGroup1', 'TODO'] && matcharg(2) == ['MyGroup2', 'FIXME'] && matcharg(3) == ['MyGroup3', 'XXX']
5050+: let @r .= "OK\n"
5051+:else
5052+: let @r .= "FAILED\n"
5053+:endif
5054+:" --- Check that "matcharg()" returns an empty list if the argument is not 1,
5055+:" --- 2 or 3 (only 0 and 4 are tested).
5056+:let @r .= "*** Test 2: "
5057+:if matcharg(0) == [] && matcharg(4) == []
5058+: let @r .= "OK\n"
5059+:else
5060+: let @r .= "FAILED\n"
5061+:endif
5062+:" --- Check that "matcharg()" returns ['', ''] if a match is not defined.
5063+:let @r .= "*** Test 3: "
5064+:match
5065+:2match
5066+:3match
5067+:if matcharg(1) == ['', ''] && matcharg(2) == ['', ''] && matcharg(3) == ['', '']
5068+: let @r .= "OK\n"
5069+:else
5070+: let @r .= "FAILED\n"
5071+:endif
5072+:" --- Check that "matchadd()" and "getmatches()" agree on added matches and
5073+:" --- that default values apply.
5074+:let @r .= "*** Test 4: "
5075+:let m1 = matchadd("MyGroup1", "TODO")
5076+:let m2 = matchadd("MyGroup2", "FIXME", 42)
5077+:let m3 = matchadd("MyGroup3", "XXX", 60, 17)
5078+: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}]
5079+: let @r .= "OK\n"
5080+:else
5081+: let @r .= "FAILED\n"
5082+:endif
5083+:" --- Check that "matchdelete()" deletes the matches defined in the previous
5084+:" --- test correctly.
5085+:let @r .= "*** Test 5: "
5086+:call matchdelete(m1)
5087+:call matchdelete(m2)
5088+:call matchdelete(m3)
5089+:unlet m1
5090+:unlet m2
5091+:unlet m3
5092+:if getmatches() == []
5093+: let @r .= "OK\n"
5094+:else
5095+: let @r .= "FAILED\n"
5096+:endif
5097+:" --- Check that "matchdelete()" returns 0 if succesfull and otherwise -1.
5098+:let @r .= "*** Test 6: "
5099+:let m = matchadd("MyGroup1", "TODO")
5100+:let r1 = matchdelete(m)
5101+:let r2 = matchdelete(42)
5102+:if r1 == 0 && r2 == -1
5103+: let @r .= "OK\n"
5104+:else
5105+: let @r .= "FAILED\n"
5106+:endif
5107+:unlet m
5108+:unlet r1
5109+:unlet r2
5110+:" --- Check that "clearmatches()" clears all matches defined by ":match" and
5111+:" --- "matchadd()".
5112+:let @r .= "*** Test 7: "
5113+:let m1 = matchadd("MyGroup1", "TODO")
5114+:let m2 = matchadd("MyGroup2", "FIXME", 42)
5115+:let m3 = matchadd("MyGroup3", "XXX", 60, 17)
5116+:match MyGroup1 /COFFEE/
5117+:2match MyGroup2 /HUMPPA/
5118+:3match MyGroup3 /VIM/
5119+:call clearmatches()
5120+:if getmatches() == []
5121+: let @r .= "OK\n"
5122+:else
5123+: let @r .= "FAILED\n"
5124+:endif
5125+:unlet m1
5126+:unlet m2
5127+:unlet m3
5128+:" --- Check that "setmatches()" restores a list of matches saved by
5129+:" --- "getmatches()" without changes. (Matches with equal priority must also
5130+:" --- remain in the same order.)
5131+:let @r .= "*** Test 8: "
5132+:let m1 = matchadd("MyGroup1", "TODO")
5133+:let m2 = matchadd("MyGroup2", "FIXME", 42)
5134+:let m3 = matchadd("MyGroup3", "XXX", 60, 17)
5135+:match MyGroup1 /COFFEE/
5136+:2match MyGroup2 /HUMPPA/
5137+:3match MyGroup3 /VIM/
5138+:let ml = getmatches()
5139+:call clearmatches()
5140+:call setmatches(ml)
5141+:if getmatches() == ml
5142+: let @r .= "OK\n"
5143+:else
5144+: let @r .= "FAILED\n"
5145+:endif
5146+:call clearmatches()
5147+:unlet m1
5148+:unlet m2
5149+:unlet m3
5150+:unlet ml
5151+:" --- Check that "setmatches()" will not add two matches with the same ID. The
5152+:" --- expected behaviour (for now) is to add the first match but not the
5153+:" --- second and to return 0 (even though it is a matter of debate whether
5154+:" --- this can be considered succesfull behaviour).
5155+:let @r .= "*** Test 9: "
5156+:let r1 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 10, 'id': 1}])
5157+:if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}] && r1 == 0
5158+: let @r .= "OK\n"
5159+:else
5160+: let @r .= "FAILED\n"
5161+:endif
5162+:call clearmatches()
5163+:unlet r1
5164+:" --- Check that "setmatches()" returns 0 if succesfull and otherwise -1.
5165+:" --- (A range of valid and invalid input values are tried out to generate the
5166+:" --- return values.)
5167+:let @r .= "*** Test 10: "
5168+:let rs1 = setmatches([])
5169+:let rs2 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}])
5170+:call clearmatches()
5171+:let rf1 = setmatches(0)
5172+:let rf2 = setmatches([0])
5173+:let rf3 = setmatches([{'wrong key': 'wrong value'}])
5174+:if rs1 == 0 && rs2 == 0 && rf1 == -1 && rf2 == -1 && rf3 == -1
5175+: let @r .= "OK\n"
5176+:else
5177+: let @r .= "FAILED\n"
5178+:endif
5179+:unlet rs1
5180+:unlet rs2
5181+:unlet rf1
5182+:unlet rf2
5183+:unlet rf3
5184+:highlight clear MyGroup1
5185+:highlight clear MyGroup2
5186+:highlight clear MyGroup3
5187+G"rp
5188+:/^Results/,$wq! test.out
5189+ENDTEST
5190+
5191+Results of test63:
5192diff -Naur vim71.orig/src/testdir/test63.ok vim71/src/testdir/test63.ok
5193--- vim71.orig/src/testdir/test63.ok 1969-12-31 16:00:00.000000000 -0800
5194+++ vim71/src/testdir/test63.ok 2007-09-03 22:13:43.000000000 -0700
5195@@ -0,0 +1,11 @@
5196+Results of test63:
5197+*** Test 1: OK
5198+*** Test 2: OK
5199+*** Test 3: OK
5200+*** Test 4: OK
5201+*** Test 5: OK
5202+*** Test 6: OK
5203+*** Test 7: OK
5204+*** Test 8: OK
5205+*** Test 9: OK
5206+*** Test 10: OK
5207diff -Naur vim71.orig/src/testdir/test64.in vim71/src/testdir/test64.in
5208--- vim71.orig/src/testdir/test64.in 1969-12-31 16:00:00.000000000 -0800
5209+++ vim71/src/testdir/test64.in 2007-09-03 22:14:54.000000000 -0700
5210@@ -0,0 +1,52 @@
5211+Test for regexp patterns.
5212+
5213+A pattern that gives the expected result produces OK, so that we know it was
5214+actually tried.
5215+
5216+STARTTEST
5217+:so small.vim
5218+:" tl is a List of Lists with:
5219+:" regexp pattern
5220+:" text to test the pattern on
5221+:" expected match (optional)
5222+:" expected submatch 1 (optional)
5223+:" expected submatch 2 (optional)
5224+:" etc.
5225+:" When there is no match use only the first two items.
5226+:let tl = []
5227+:call add(tl, ['b', 'abcdef', 'b'])
5228+:call add(tl, ['bc*', 'abccccdef', 'bcccc'])
5229+:call add(tl, ['bc\{-}', 'abccccdef', 'b'])
5230+:call add(tl, ['bc\{-}\(d\)', 'abccccdef', 'bccccd', 'd'])
5231+:call add(tl, ['x', 'abcdef'])
5232+:"
5233+:for t in tl
5234+: let l = matchlist(t[1], t[0])
5235+:" check the match itself
5236+: if len(l) == 0 && len(t) > 2
5237+: $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", did not match, expected: \"' . t[2] . '\"'
5238+: elseif len(l) > 0 && len(t) == 2
5239+: $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", match: \"' . l[0] . '\", expected no match'
5240+: elseif len(t) > 2 && l[0] != t[2]
5241+: $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", match: \"' . l[0] . '\", expected: \"' . t[2] . '\"'
5242+: else
5243+: $put ='OK'
5244+: endif
5245+: if len(l) > 0
5246+:" check all the nine submatches
5247+: for i in range(1, 9)
5248+: if len(t) <= i + 2
5249+: let e = ''
5250+: else
5251+: let e = t[i + 2]
5252+: endif
5253+: if l[i] != e
5254+: $put ='ERROR: pat: \"' . t[0] . '\", text: \"' . t[1] . '\", submatch ' . i . ': \"' . l[i] . '\", expected: \"' . e . '\"'
5255+: endif
5256+: endfor
5257+: endif
5258+:endfor
5259+:/^Results/,$wq! test.out
5260+ENDTEST
5261+
5262+Results of test64:
5263diff -Naur vim71.orig/src/testdir/test64.ok vim71/src/testdir/test64.ok
5264--- vim71.orig/src/testdir/test64.ok 1969-12-31 16:00:00.000000000 -0800
5265+++ vim71/src/testdir/test64.ok 2007-09-03 22:14:54.000000000 -0700
5266@@ -0,0 +1,6 @@
5267+Results of test64:
5268+OK
5269+OK
5270+OK
5271+OK
5272+OK
5273diff -Naur vim71.orig/src/ui.c vim71/src/ui.c
5274--- vim71.orig/src/ui.c 2007-05-07 12:49:09.000000000 -0700
5275+++ vim71/src/ui.c 2007-09-03 22:15:10.000000000 -0700
5276@@ -1603,8 +1603,6 @@
5277 #if defined(FEAT_GUI) || defined(FEAT_MOUSE_GPM) \
5278 || defined(FEAT_XCLIPBOARD) || defined(VMS) \
5279 || defined(FEAT_SNIFF) || defined(FEAT_CLIENTSERVER) \
5280- || (defined(FEAT_GUI) && (!defined(USE_ON_FLY_SCROLL) \
5281- || defined(FEAT_MENU))) \
5282 || defined(PROTO)
5283 /*
5284 * Add the given bytes to the input buffer
5285@@ -1630,7 +1628,9 @@
5286 }
5287 #endif
5288
5289-#if (defined(FEAT_XIM) && defined(FEAT_GUI_GTK)) \
5290+#if ((defined(FEAT_XIM) || defined(FEAT_DND)) && defined(FEAT_GUI_GTK)) \
5291+ || defined(FEAT_GUI_MSWIN) \
5292+ || defined(FEAT_GUI_MAC) \
5293 || (defined(FEAT_MBYTE) && defined(FEAT_MBYTE_IME)) \
5294 || (defined(FEAT_GUI) && (!defined(USE_ON_FLY_SCROLL) \
5295 || defined(FEAT_MENU))) \
5296diff -Naur vim71.orig/src/version.c vim71/src/version.c
5297--- vim71.orig/src/version.c 2007-05-12 03:23:44.000000000 -0700
5298+++ vim71/src/version.c 2007-09-03 22:15:47.000000000 -0700
5299@@ -667,6 +667,174 @@
5300 static int included_patches[] =
5301 { /* Add new patch number below this line */
5302 /**/
5303+ 94,
5304+/**/
5305+ 93,
5306+/**/
5307+ 90,
5308+/**/
5309+ 89,
5310+/**/
5311+ 87,
5312+/**/
5313+ 86,
5314+/**/
5315+ 85,
5316+/**/
5317+ 84,
5318+/**/
5319+ 83,
5320+/**/
5321+ 82,
5322+/**/
5323+ 81,
5324+/**/
5325+ 79,
5326+/**/
5327+ 78,
5328+/**/
5329+ 77,
5330+/**/
5331+ 76,
5332+/**/
5333+ 75,
5334+/**/
5335+ 74,
5336+/**/
5337+ 73,
5338+/**/
5339+ 71,
5340+/**/
5341+ 69,
5342+/**/
5343+ 68,
5344+/**/
5345+ 67,
5346+/**/
5347+ 66,
5348+/**/
5349+ 64,
5350+/**/
5351+ 63,
5352+/**/
5353+ 62,
5354+/**/
5355+ 61,
5356+/**/
5357+ 60,
5358+/**/
5359+ 59,
5360+/**/
5361+ 58,
5362+/**/
5363+ 57,
5364+/**/
5365+ 56,
5366+/**/
5367+ 55,
5368+/**/
5369+ 54,
5370+/**/
5371+ 53,
5372+/**/
5373+ 52,
5374+/**/
5375+ 51,
5376+/**/
5377+ 50,
5378+/**/
5379+ 49,
5380+/**/
5381+ 48,
5382+/**/
5383+ 47,
5384+/**/
5385+ 46,
5386+/**/
5387+ 45,
5388+/**/
5389+ 44,
5390+/**/
5391+ 43,
5392+/**/
5393+ 42,
5394+/**/
5395+ 40,
5396+/**/
5397+ 39,
5398+/**/
5399+ 38,
5400+/**/
5401+ 37,
5402+/**/
5403+ 36,
5404+/**/
5405+ 35,
5406+/**/
5407+ 34,
5408+/**/
5409+ 33,
5410+/**/
5411+ 32,
5412+/**/
5413+ 31,
5414+/**/
5415+ 30,
5416+/**/
5417+ 29,
5418+/**/
5419+ 28,
5420+/**/
5421+ 27,
5422+/**/
5423+ 26,
5424+/**/
5425+ 25,
5426+/**/
5427+ 24,
5428+/**/
5429+ 23,
5430+/**/
5431+ 22,
5432+/**/
5433+ 21,
5434+/**/
5435+ 20,
5436+/**/
5437+ 19,
5438+/**/
5439+ 18,
5440+/**/
5441+ 17,
5442+/**/
5443+ 16,
5444+/**/
5445+ 15,
5446+/**/
5447+ 14,
5448+/**/
5449+ 13,
5450+/**/
5451+ 12,
5452+/**/
5453+ 11,
5454+/**/
5455+ 10,
5456+/**/
5457+ 9,
5458+/**/
5459+ 8,
5460+/**/
5461+ 6,
5462+/**/
5463+ 5,
5464+/**/
5465+ 4,
5466+/**/
5467+ 2,
5468+/**/
5469+ 1,
5470+/**/
5471 0
5472 };
5473
5474diff -Naur vim71.orig/src/vim.h vim71/src/vim.h
5475--- vim71.orig/src/vim.h 2007-05-12 02:53:29.000000000 -0700
5476+++ vim71/src/vim.h 2007-09-03 22:14:31.000000000 -0700
5477@@ -1380,8 +1380,14 @@
5478 #endif
5479
5480 #ifdef FEAT_MBYTE
5481-# define MB_STRICMP(d, s) (has_mbyte ? mb_strnicmp((char_u *)(d), (char_u *)(s), (int)MAXCOL) : STRICMP((d), (s)))
5482-# define MB_STRNICMP(d, s, n) (has_mbyte ? mb_strnicmp((char_u *)(d), (char_u *)(s), (int)(n)) : STRNICMP((d), (s), (n)))
5483+/* We need to call mb_stricmp() even when we aren't dealing with a multi-byte
5484+ * encoding because mb_stricmp() takes care of all ascii and non-ascii
5485+ * encodings, including characters with umluats in latin1, etc., while
5486+ * STRICMP() only handles the system locale version, which often does not
5487+ * handle non-ascii properly. */
5488+
5489+# define MB_STRICMP(d, s) mb_strnicmp((char_u *)(d), (char_u *)(s), (int)MAXCOL)
5490+# define MB_STRNICMP(d, s, n) mb_strnicmp((char_u *)(d), (char_u *)(s), (int)(n))
5491 #else
5492 # define MB_STRICMP(d, s) STRICMP((d), (s))
5493 # define MB_STRNICMP(d, s, n) STRNICMP((d), (s), (n))
5494diff -Naur vim71.orig/src/vimtutor vim71/src/vimtutor
5495--- vim71.orig/src/vimtutor 2004-06-07 07:32:27.000000000 -0700
5496+++ vim71/src/vimtutor 2007-09-03 22:13:19.000000000 -0700
5497@@ -39,18 +39,22 @@
5498 # remove the copy of the tutor on exit
5499 trap "rm -rf $TODELETE" 0 1 2 3 9 11 13 15
5500
5501-# Vim could be called "vim" or "vi". Also check for "vim6", for people who
5502-# have Vim 5.x installed as "vim" and Vim 6.0 as "vim6".
5503-testvim=`which vim6 2>/dev/null`
5504-if test -f "$testvim"; then
5505- VIM=vim6
5506-else
5507- testvim=`which vim`
5508+# Vim could be called "vim" or "vi". Also check for "vimN", for people who
5509+# have Vim installed with its version number.
5510+# We anticipate up to a future Vim 8 version :-).
5511+seq="vim vim8 vim75 vim74 vim73 vim72 vim71 vim70 vim7 vim6 vi"
5512+for i in $seq; do
5513+ testvim=`which $i 2>/dev/null`
5514 if test -f "$testvim"; then
5515- VIM=vim
5516- else
5517- VIM=vi
5518+ VIM=$i
5519+ break
5520 fi
5521+done
5522+
5523+# When no Vim version was found fall back to "vim", you'll get an error message
5524+# below.
5525+if test -z "$VIM"; then
5526+ VIM=vim
5527 fi
5528
5529 # Use Vim to copy the tutor, it knows the value of $VIMRUNTIME
5530diff -Naur vim71.orig/src/window.c vim71/src/window.c
5531--- vim71.orig/src/window.c 2007-05-07 12:25:30.000000000 -0700
5532+++ vim71/src/window.c 2007-09-03 22:14:47.000000000 -0700
5533@@ -75,6 +75,7 @@
5534 static win_T *restore_snapshot_rec __ARGS((frame_T *sn, frame_T *fr));
5535
5536 #endif /* FEAT_WINDOWS */
5537+
5538 static win_T *win_alloc __ARGS((win_T *after));
5539 static void win_new_height __ARGS((win_T *, int));
5540
5541@@ -732,7 +733,6 @@
5542 if (flags & WSP_VERT)
5543 {
5544 layout = FR_ROW;
5545- do_equal = (p_ea && new_size == 0 && *p_ead != 'v');
5546
5547 /*
5548 * Check if we are able to split the current window and compute its
5549@@ -769,16 +769,31 @@
5550 * instead, if possible. */
5551 if (oldwin->w_p_wfw)
5552 win_setwidth_win(oldwin->w_width + new_size, oldwin);
5553+
5554+ /* Only make all windows the same width if one of them (except oldwin)
5555+ * is wider than one of the split windows. */
5556+ if (!do_equal && p_ea && size == 0 && *p_ead != 'v'
5557+ && oldwin->w_frame->fr_parent != NULL)
5558+ {
5559+ frp = oldwin->w_frame->fr_parent->fr_child;
5560+ while (frp != NULL)
5561+ {
5562+ if (frp->fr_win != oldwin && frp->fr_win != NULL
5563+ && (frp->fr_win->w_width > new_size
5564+ || frp->fr_win->w_width > oldwin->w_width
5565+ - new_size - STATUS_HEIGHT))
5566+ {
5567+ do_equal = TRUE;
5568+ break;
5569+ }
5570+ frp = frp->fr_next;
5571+ }
5572+ }
5573 }
5574 else
5575 #endif
5576 {
5577 layout = FR_COL;
5578- do_equal = (p_ea && new_size == 0
5579-#ifdef FEAT_VERTSPLIT
5580- && *p_ead != 'h'
5581-#endif
5582- );
5583
5584 /*
5585 * Check if we are able to split the current window and compute its
5586@@ -831,6 +846,29 @@
5587 if (need_status)
5588 oldwin_height -= STATUS_HEIGHT;
5589 }
5590+
5591+ /* Only make all windows the same height if one of them (except oldwin)
5592+ * is higher than one of the split windows. */
5593+ if (!do_equal && p_ea && size == 0
5594+#ifdef FEAT_VERTSPLIT
5595+ && *p_ead != 'h'
5596+#endif
5597+ && oldwin->w_frame->fr_parent != NULL)
5598+ {
5599+ frp = oldwin->w_frame->fr_parent->fr_child;
5600+ while (frp != NULL)
5601+ {
5602+ if (frp->fr_win != oldwin && frp->fr_win != NULL
5603+ && (frp->fr_win->w_height > new_size
5604+ || frp->fr_win->w_height > oldwin_height - new_size
5605+ - STATUS_HEIGHT))
5606+ {
5607+ do_equal = TRUE;
5608+ break;
5609+ }
5610+ frp = frp->fr_next;
5611+ }
5612+ }
5613 }
5614
5615 /*
5616@@ -2120,7 +2158,7 @@
5617 if (wp->w_p_pvw || bt_quickfix(wp->w_buffer))
5618 {
5619 /*
5620- * The cursor goes to the preview or the quickfix window, try
5621+ * If the cursor goes to the preview or the quickfix window, try
5622 * finding another window to go to.
5623 */
5624 for (;;)
5625@@ -2307,7 +2345,6 @@
5626 frame_T *frp, *frp2, *frp3;
5627 frame_T *frp_close = win->w_frame;
5628 win_T *wp;
5629- int old_size = 0;
5630
5631 /*
5632 * If there is only one window there is nothing to remove.
5633@@ -2328,33 +2365,77 @@
5634 if (frp_close->fr_parent->fr_layout == FR_COL)
5635 {
5636 #endif
5637- /* When 'winfixheight' is set, remember its old size and restore
5638- * it later (it's a simplistic solution...). Don't do this if the
5639- * window will occupy the full height of the screen. */
5640- if (frp2->fr_win != NULL
5641- && (frp2->fr_next != NULL || frp2->fr_prev != NULL)
5642- && frp2->fr_win->w_p_wfh)
5643- old_size = frp2->fr_win->w_height;
5644+ /* When 'winfixheight' is set, try to find another frame in the column
5645+ * (as close to the closed frame as possible) to distribute the height
5646+ * to. */
5647+ if (frp2->fr_win != NULL && frp2->fr_win->w_p_wfh)
5648+ {
5649+ frp = frp_close->fr_prev;
5650+ frp3 = frp_close->fr_next;
5651+ while (frp != NULL || frp3 != NULL)
5652+ {
5653+ if (frp != NULL)
5654+ {
5655+ if (frp->fr_win != NULL && !frp->fr_win->w_p_wfh)
5656+ {
5657+ frp2 = frp;
5658+ wp = frp->fr_win;
5659+ break;
5660+ }
5661+ frp = frp->fr_prev;
5662+ }
5663+ if (frp3 != NULL)
5664+ {
5665+ if (frp3->fr_win != NULL && !frp3->fr_win->w_p_wfh)
5666+ {
5667+ frp2 = frp3;
5668+ wp = frp3->fr_win;
5669+ break;
5670+ }
5671+ frp3 = frp3->fr_next;
5672+ }
5673+ }
5674+ }
5675 frame_new_height(frp2, frp2->fr_height + frp_close->fr_height,
5676 frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE);
5677- if (old_size != 0)
5678- win_setheight_win(old_size, frp2->fr_win);
5679 #ifdef FEAT_VERTSPLIT
5680 *dirp = 'v';
5681 }
5682 else
5683 {
5684- /* When 'winfixwidth' is set, remember its old size and restore
5685- * it later (it's a simplistic solution...). Don't do this if the
5686- * window will occupy the full width of the screen. */
5687- if (frp2->fr_win != NULL
5688- && (frp2->fr_next != NULL || frp2->fr_prev != NULL)
5689- && frp2->fr_win->w_p_wfw)
5690- old_size = frp2->fr_win->w_width;
5691+ /* When 'winfixwidth' is set, try to find another frame in the column
5692+ * (as close to the closed frame as possible) to distribute the width
5693+ * to. */
5694+ if (frp2->fr_win != NULL && frp2->fr_win->w_p_wfw)
5695+ {
5696+ frp = frp_close->fr_prev;
5697+ frp3 = frp_close->fr_next;
5698+ while (frp != NULL || frp3 != NULL)
5699+ {
5700+ if (frp != NULL)
5701+ {
5702+ if (frp->fr_win != NULL && !frp->fr_win->w_p_wfw)
5703+ {
5704+ frp2 = frp;
5705+ wp = frp->fr_win;
5706+ break;
5707+ }
5708+ frp = frp->fr_prev;
5709+ }
5710+ if (frp3 != NULL)
5711+ {
5712+ if (frp3->fr_win != NULL && !frp3->fr_win->w_p_wfw)
5713+ {
5714+ frp2 = frp3;
5715+ wp = frp3->fr_win;
5716+ break;
5717+ }
5718+ frp3 = frp3->fr_next;
5719+ }
5720+ }
5721+ }
5722 frame_new_width(frp2, frp2->fr_width + frp_close->fr_width,
5723 frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE);
5724- if (old_size != 0)
5725- win_setwidth_win(old_size, frp2->fr_win);
5726 *dirp = 'h';
5727 }
5728 #endif
5729@@ -4128,6 +4209,10 @@
5730 #ifdef FEAT_AUTOCMD
5731 --autocmd_block;
5732 #endif
5733+#ifdef FEAT_SEARCH_EXTRA
5734+ newwin->w_match_head = NULL;
5735+ newwin->w_next_match_id = 4;
5736+#endif
5737 }
5738 return newwin;
5739 }
5740@@ -4185,11 +4270,11 @@
5741 vim_free(wp->w_tagstack[i].tagname);
5742
5743 vim_free(wp->w_localdir);
5744+
5745 #ifdef FEAT_SEARCH_EXTRA
5746- vim_free(wp->w_match[0].regprog);
5747- vim_free(wp->w_match[1].regprog);
5748- vim_free(wp->w_match[2].regprog);
5749+ clear_matches(wp);
5750 #endif
5751+
5752 #ifdef FEAT_JUMPLIST
5753 free_jumplist(wp);
5754 #endif
5755@@ -6174,3 +6259,175 @@
5756 return FALSE;
5757 }
5758 #endif
5759+
5760+#if defined(FEAT_SEARCH_EXTRA) || defined(PROTO)
5761+/*
5762+ * Add match to the match list of window 'wp'. The pattern 'pat' will be
5763+ * highligted with the group 'grp' with priority 'prio'.
5764+ * Optionally, a desired ID 'id' can be specified (greater than or equal to 1).
5765+ * If no particular ID is desired, -1 must be specified for 'id'.
5766+ * Return ID of added match, -1 on failure.
5767+ */
5768+ int
5769+match_add(wp, grp, pat, prio, id)
5770+ win_T *wp;
5771+ char_u *grp;
5772+ char_u *pat;
5773+ int prio;
5774+ int id;
5775+{
5776+ matchitem_T *cur;
5777+ matchitem_T *prev;
5778+ matchitem_T *m;
5779+ int hlg_id;
5780+ regprog_T *regprog;
5781+
5782+ if (*grp == NUL || *pat == NUL)
5783+ return -1;
5784+ if (id < -1 || id == 0)
5785+ {
5786+ EMSGN("E799: Invalid ID: %ld (must be greater than or equal to 1)", id);
5787+ return -1;
5788+ }
5789+ if (id != -1)
5790+ {
5791+ cur = wp->w_match_head;
5792+ while (cur != NULL)
5793+ {
5794+ if (cur->id == id)
5795+ {
5796+ EMSGN("E801: ID already taken: %ld", id);
5797+ return -1;
5798+ }
5799+ cur = cur->next;
5800+ }
5801+ }
5802+ if ((hlg_id = syn_namen2id(grp, STRLEN(grp))) == 0)
5803+ {
5804+ EMSG2(_(e_nogroup), grp);
5805+ return -1;
5806+ }
5807+ if ((regprog = vim_regcomp(pat, RE_MAGIC)) == NULL)
5808+ {
5809+ EMSG2(_(e_invarg2), pat);
5810+ return -1;
5811+ }
5812+
5813+ /* Find available match ID. */
5814+ while (id == -1)
5815+ {
5816+ cur = wp->w_match_head;
5817+ while (cur != NULL && cur->id != wp->w_next_match_id)
5818+ cur = cur->next;
5819+ if (cur == NULL)
5820+ id = wp->w_next_match_id;
5821+ wp->w_next_match_id++;
5822+ }
5823+
5824+ /* Build new match. */
5825+ m = (matchitem_T *)alloc(sizeof(matchitem_T));
5826+ m->id = id;
5827+ m->priority = prio;
5828+ m->pattern = vim_strsave(pat);
5829+ m->hlg_id = hlg_id;
5830+ m->match.regprog = regprog;
5831+ m->match.rmm_ic = FALSE;
5832+ m->match.rmm_maxcol = 0;
5833+
5834+ /* Insert new match. The match list is in ascending order with regard to
5835+ * the match priorities. */
5836+ cur = wp->w_match_head;
5837+ prev = cur;
5838+ while (cur != NULL && prio >= cur->priority)
5839+ {
5840+ prev = cur;
5841+ cur = cur->next;
5842+ }
5843+ if (cur == prev)
5844+ wp->w_match_head = m;
5845+ else
5846+ prev->next = m;
5847+ m->next = cur;
5848+
5849+ redraw_later(SOME_VALID);
5850+ return id;
5851+}
5852+
5853+/*
5854+ * Delete match with ID 'id' in the match list of window 'wp'.
5855+ * Print error messages if 'perr' is TRUE.
5856+ */
5857+ int
5858+match_delete(wp, id, perr)
5859+ win_T *wp;
5860+ int id;
5861+ int perr;
5862+{
5863+ matchitem_T *cur = wp->w_match_head;
5864+ matchitem_T *prev = cur;
5865+
5866+ if (id < 1)
5867+ {
5868+ if (perr == TRUE)
5869+ EMSGN("E802: Invalid ID: %ld (must be greater than or equal to 1)",
5870+ id);
5871+ return -1;
5872+ }
5873+ while (cur != NULL && cur->id != id)
5874+ {
5875+ prev = cur;
5876+ cur = cur->next;
5877+ }
5878+ if (cur == NULL)
5879+ {
5880+ if (perr == TRUE)
5881+ EMSGN("E803: ID not found: %ld", id);
5882+ return -1;
5883+ }
5884+ if (cur == prev)
5885+ wp->w_match_head = cur->next;
5886+ else
5887+ prev->next = cur->next;
5888+ vim_free(cur->match.regprog);
5889+ vim_free(cur->pattern);
5890+ vim_free(cur);
5891+ redraw_later(SOME_VALID);
5892+ return 0;
5893+}
5894+
5895+/*
5896+ * Delete all matches in the match list of window 'wp'.
5897+ */
5898+ void
5899+clear_matches(wp)
5900+ win_T *wp;
5901+{
5902+ matchitem_T *m;
5903+
5904+ while (wp->w_match_head != NULL)
5905+ {
5906+ m = wp->w_match_head->next;
5907+ vim_free(wp->w_match_head->match.regprog);
5908+ vim_free(wp->w_match_head->pattern);
5909+ vim_free(wp->w_match_head);
5910+ wp->w_match_head = m;
5911+ }
5912+ redraw_later(SOME_VALID);
5913+}
5914+
5915+/*
5916+ * Get match from ID 'id' in window 'wp'.
5917+ * Return NULL if match not found.
5918+ */
5919+ matchitem_T *
5920+get_match(wp, id)
5921+ win_T *wp;
5922+ int id;
5923+{
5924+ matchitem_T *cur = wp->w_match_head;
5925+
5926+ while (cur != NULL && cur->id != id)
5927+ cur = cur->next;
5928+ return cur;
5929+}
5930+#endif
Note: See TracBrowser for help on using the repository browser.