Submitted By: Jim Gifford (jim at linuxfromscratch dot org)
Date: 11-29-2006
Initial Package Version: 7.0
Origin: Upstream
Upstream Status: Applied
Description: Contains all upstream patches up to 7.0.174
             The following patches were skipped
             005 027 028 032 045 057 065 074 108 130 131 132 138 156 161 170 171

diff -Naur vim70.orig/configure vim70/configure
--- vim70.orig/configure	2004-07-05 02:02:24.000000000 -0700
+++ vim70/configure	2006-11-29 16:09:55.000000000 -0800
@@ -3,4 +3,4 @@
 # This is just a stub for the Unix configure script, to provide support for
 # doing "./configure" in the top Vim directory.
 
-cd src && ./configure "$@"
+cd src && exec ./configure "$@"
diff -Naur vim70.orig/runtime/autoload/ccomplete.vim vim70/runtime/autoload/ccomplete.vim
--- vim70.orig/runtime/autoload/ccomplete.vim	2006-05-03 07:35:56.000000000 -0700
+++ vim70/runtime/autoload/ccomplete.vim	2006-11-29 16:09:49.000000000 -0800
@@ -1,7 +1,7 @@
 " Vim completion script
 " Language:	C
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2006 May 03
+" Last Change:	2006 May 08
 
 
 " This function is used for the 'omnifunc' option.
@@ -458,7 +458,7 @@
 " member.
 function! s:StructMembers(typename, items, all)
   " Todo: What about local structures?
-  let fnames = join(map(tagfiles(), 'escape(v:val, " \\")'))
+  let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")'))
   if fnames == ''
     return []
   endif
diff -Naur vim70.orig/runtime/autoload/gzip.vim vim70/runtime/autoload/gzip.vim
--- vim70.orig/runtime/autoload/gzip.vim	2006-03-31 07:12:15.000000000 -0800
+++ vim70/runtime/autoload/gzip.vim	2006-11-29 16:10:07.000000000 -0800
@@ -1,6 +1,6 @@
 " Vim autoload file for editing compressed files.
 " Maintainer: Bram Moolenaar <Bram@vim.org>
-" Last Change: 2006 Mar 31
+" Last Change: 2006 Oct 03
 
 " These functions are used by the gzip plugin.
 
@@ -68,9 +68,9 @@
   let tmp = tempname()
   let tmpe = tmp . "." . expand("<afile>:e")
   " write the just read lines to a temp file "'[,']w tmp.gz"
-  execute "silent '[,']w " . tmpe
+  execute "silent '[,']w " . escape(tmpe, ' ')
   " uncompress the temp file: call system("gzip -dn tmp.gz")
-  call system(a:cmd . " " . tmpe)
+  call system(a:cmd . " " . s:escape(tmpe))
   if !filereadable(tmp)
     " uncompress didn't work!  Keep the compressed file then.
     echoerr "Error: Could not read uncompressed file"
@@ -127,9 +127,9 @@
     let nmt = s:tempname(nm)
     if rename(nm, nmt) == 0
       if exists("b:gzip_comp_arg")
-	call system(a:cmd . " " . b:gzip_comp_arg . " " . nmt)
+	call system(a:cmd . " " . b:gzip_comp_arg . " " . s:escape(nmt))
       else
-	call system(a:cmd . " " . nmt)
+	call system(a:cmd . " " . s:escape(nmt))
       endif
       call rename(nmt . "." . expand("<afile>:e"), nm)
     endif
@@ -154,10 +154,10 @@
     if rename(nm, nmte) == 0
       if &patchmode != "" && getfsize(nm . &patchmode) == -1
 	" Create patchmode file by creating the decompressed file new
-	call system(a:cmd . " -c " . nmte . " > " . nmt)
+	call system(a:cmd . " -c " . s:escape(nmte) . " > " . s:escape(nmt))
 	call rename(nmte, nm . &patchmode)
       else
-	call system(a:cmd . " " . nmte)
+	call system(a:cmd . " " . s:escape(nmte))
       endif
       call rename(nmt, nm)
     endif
@@ -175,4 +175,12 @@
   return fnamemodify(a:name, ":p:h") . "/X~=@l9q5"
 endfun
 
+fun s:escape(name)
+  " shellescape() was added by patch 7.0.111
+  if v:version > 700 || (v:version == 700 && has('patch111'))
+    return shellescape(a:name)
+  endif
+  return "'" . a:name . "'"
+endfun
+
 " vim: set sw=2 :
diff -Naur vim70.orig/runtime/autoload/paste.vim vim70/runtime/autoload/paste.vim
--- vim70.orig/runtime/autoload/paste.vim	2006-04-21 11:31:01.000000000 -0700
+++ vim70/runtime/autoload/paste.vim	2006-11-29 16:09:53.000000000 -0800
@@ -1,6 +1,6 @@
 " Vim support file to help with paste mappings and menus
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2006 Apr 21
+" Last Change:	2006 Jun 23
 
 " Define the string to use for items that are present both in Edit, Popup and
 " Toolbar menu.  Also used in mswin.vim and macmap.vim.
@@ -12,7 +12,7 @@
 if has("virtualedit")
   let paste#paste_cmd = {'n': ":call paste#Paste()<CR>"}
   let paste#paste_cmd['v'] = '"-c<Esc>' . paste#paste_cmd['n']
-  let paste#paste_cmd['i'] = '<Esc>' . paste#paste_cmd['n'] . 'gi'
+  let paste#paste_cmd['i'] = 'x<BS><Esc>' . paste#paste_cmd['n'] . 'gi'
 
   func! paste#Paste()
     let ove = &ve
diff -Naur vim70.orig/runtime/autoload/spellfile.vim vim70/runtime/autoload/spellfile.vim
--- vim70.orig/runtime/autoload/spellfile.vim	2006-02-01 04:12:24.000000000 -0800
+++ vim70/runtime/autoload/spellfile.vim	2006-11-29 16:10:01.000000000 -0800
@@ -1,9 +1,9 @@
 " Vim script to download a missing spell file
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2006 Feb 01
+" Last Change:	2006 Aug 29
 
 if !exists('g:spellfile_URL')
-  let g:spellfile_URL = 'ftp://ftp.vim.org/pub/vim/unstable/runtime/spell'
+  let g:spellfile_URL = 'ftp://ftp.vim.org/pub/vim/runtime/spell'
 endif
 let s:spellfile_URL = ''    " Start with nothing so that s:donedict is reset.
 
@@ -61,13 +61,13 @@
     new
     setlocal bin
     echo 'Downloading ' . fname . '...'
-    exe 'Nread ' g:spellfile_URL . '/' . fname
+    call spellfile#Nread(fname)
     if getline(2) !~ 'VIMspell'
       " Didn't work, perhaps there is an ASCII one.
       g/^/d
       let fname = a:lang . '.ascii.spl'
       echo 'Could not find it, trying ' . fname . '...'
-      exe 'Nread ' g:spellfile_URL . '/' . fname
+      call spellfile#Nread(fname)
       if getline(2) !~ 'VIMspell'
 	echo 'Sorry, downloading failed'
 	bwipe!
@@ -95,7 +95,7 @@
 	g/^/d
 	let fname = substitute(fname, '\.spl$', '.sug', '')
 	echo 'Downloading ' . fname . '...'
-	exe 'Nread ' g:spellfile_URL . '/' . fname
+	call spellfile#Nread(fname)
 	if getline(2) !~ 'VIMsug'
 	  echo 'Sorry, downloading failed'
 	else
@@ -109,3 +109,15 @@
     bwipe
   endif
 endfunc
+
+" Read "fname" from the server.
+function! spellfile#Nread(fname)
+  if g:spellfile_URL =~ '^ftp://'
+    " for an ftp server use a default login and password to avoid a prompt
+    let machine = substitute(g:spellfile_URL, 'ftp://\([^/]*\).*', '\1', '')
+    let dir = substitute(g:spellfile_URL, 'ftp://[^/]*/\(.*\)', '\1', '')
+    exe 'Nread "' . machine . ' anonymous vim7user ' . dir . '/' . a:fname . '"'
+  else
+    exe 'Nread ' g:spellfile_URL . '/' . a:fname
+  endif
+endfunc
diff -Naur vim70.orig/runtime/doc/eval.txt vim70/runtime/doc/eval.txt
--- vim70.orig/runtime/doc/eval.txt	2006-05-07 05:16:44.000000000 -0700
+++ vim70/runtime/doc/eval.txt	2006-11-29 16:10:14.000000000 -0800
@@ -1,4 +1,4 @@
-*eval.txt*      For Vim version 7.0.  Last change: 2006 May 06
+*eval.txt*      For Vim version 7.0.  Last change: 2006 Nov 01
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1374,6 +1374,21 @@
 		'guitabtooltip'.  Only valid while one of these expressions is
 		being evaluated.  Read-only when in the |sandbox|.
 
+					*v:mouse_win* *mouse_win-variable*
+v:mouse_win	Window number for a mouse click obtained with |getchar()|.
+		First window has number 1, like with |winnr()|.  The value is
+		zero when there was no mouse button click.
+
+					*v:mouse_lnum* *mouse_lnum-variable*
+v:mouse_lnum	Line number for a mouse click obtained with |getchar()|.
+		This is the text line number, not the screen line number.  The
+		value is zero when there was no mouse button click.
+
+					*v:mouse_col* *mouse_col-variable*
+v:mouse_col	Column number for a mouse click obtained with |getchar()|.
+		This is the screen column number, like with |virtcol()|.  The
+		value is zero when there was no mouse button click.
+
 					*v:prevcount* *prevcount-variable*
 v:prevcount	The count given for the last but one Normal mode command.
 		This is the v:count value of the previous command.  Useful if
@@ -1709,6 +1724,8 @@
 settabwinvar( {tabnr}, {winnr}, {varname}, {val})    set {varname} in window
 					{winnr} in tab page {tabnr} to {val}
 setwinvar( {nr}, {varname}, {val})	set {varname} in window {nr} to {val}
+shellescape( {string})		String	escape {string} for use as shell
+					command argument
 simplify( {filename})		String	simplify filename as much as possible
 sort( {list} [, {func}])	List	sort {list}, using {func} to compare
 soundfold( {word})		String	sound-fold {word}
@@ -2700,6 +2717,17 @@
 		one-byte character it is the character itself as a number.
 		Use nr2char() to convert it to a String.
 
+		When the user clicks a mouse button, the mouse event will be
+		returned.  The position can then be found in |v:mouse_col|,
+		|v:mouse_lnum| and |v:mouse_win|.  This example positions the
+		mouse as it would normally happen: >
+			let c = getchar()
+		  	if c == "\<LeftMouse>" && v:mouse_win > 0
+			  exe v:mouse_win . "wincmd w"
+			  exe v:mouse_lnum
+			  exe "normal " . v:mouse_col . "|"
+			endif
+<
 		There is no prompt, you will somehow have to make clear to the
 		user that a character has to be typed.
 		There is no mapping for the character.
@@ -4434,6 +4462,21 @@
 			:call setwinvar(1, "&list", 0)
 			:call setwinvar(2, "myvar", "foobar")
 
+shellescape({string})					*shellescape()*
+		Escape {string} for use as shell command argument.
+		On MS-Windows and MS-DOS, when 'shellslash' is not set, it
+		will enclose {string} double quotes and double all double
+		quotes within {string}.
+		For other systems, it will enclose {string} in single quotes
+		and replace all "'" with "'\''".
+		Example: >
+			:echo shellescape('c:\program files\vim')
+<		results in:
+			"c:\program files\vim" ~
+		Example usage: >
+			:call system("chmod +x -- " . shellescape(expand("%")))
+
+
 simplify({filename})					*simplify()*
 		Simplify the file name as much as possible without changing
 		the meaning.  Shortcuts (on MS-Windows) or symbolic links (on
diff -Naur vim70.orig/runtime/doc/netbeans.txt vim70/runtime/doc/netbeans.txt
--- vim70.orig/runtime/doc/netbeans.txt	2006-05-07 05:16:45.000000000 -0700
+++ vim70/runtime/doc/netbeans.txt	2006-11-29 16:10:15.000000000 -0800
@@ -1,4 +1,4 @@
-*netbeans.txt*  For Vim version 7.0.  Last change: 2006 Mar 09
+*netbeans.txt*  For Vim version 7.0.  Last change: 2006 Nov 14
 
 
 		  VIM REFERENCE MANUAL    by Gordon Prieur
@@ -259,8 +259,8 @@
 confusion happening again, netbeans_saved() has been renamed to
 netbeans_save_buffer().
 
-We are now at version 2.3.  For the differences between 2.2 and 2.3 search for
-"2.3" below.
+We are now at version 2.4.  For the differences between 2.3 and 2.4 search for
+"2.4" below.
 
 The messages are currently sent over a socket.  Since the messages are in
 plain UTF-8 text this protocol could also be used with any other communication
@@ -605,6 +605,15 @@
 
 getMark		Not implemented.
 
+getAnno serNum
+		Return the line number of the annotation in the buffer.
+		Argument:
+			serNum		serial number of this placed annotation
+		The reply is:
+			123 lnum	line number of the annotation
+			123 0		invalid annotation serial number
+		New in version 2.4.
+
 getModified	When a buffer is specified: Return zero if the buffer does not
 		have changes, one if it does have changes.
 		When no buffer is specified (buffer number zero): Return the
diff -Naur vim70.orig/runtime/menu.vim vim70/runtime/menu.vim
--- vim70.orig/runtime/menu.vim	2006-04-17 06:47:28.000000000 -0700
+++ vim70/runtime/menu.vim	2006-11-29 16:10:06.000000000 -0800
@@ -2,7 +2,7 @@
 " You can also use this as a start for your own set of menus.
 "
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2006 Apr 17
+" Last Change:	2006 Sep 14
 
 " Note that ":an" (short for ":anoremenu") is often used to make a menu work
 " in all modes and avoid side effects from mappings defined by the user.
@@ -885,6 +885,8 @@
     if exists("s:changeitem") && s:changeitem != ''
       call <SID>SpellDel()
     endif
+
+    " Return quickly if spell checking is not enabled.
     if !&spell || &spelllang == ''
       return
     endif
@@ -908,18 +910,18 @@
 	let s:fromword = w
 	let pri = 1
 	for sug in s:suglist
-	  exe 'amenu 1.5.' . pri . ' PopUp.' . s:changeitem . '.' . escape(sug, ' .')
+	  exe 'anoremenu 1.5.' . pri . ' PopUp.' . s:changeitem . '.' . escape(sug, ' .')
 		\ . ' :call <SID>SpellReplace(' . pri . ')<CR>'
 	  let pri += 1
 	endfor
 
 	let s:additem = 'add\ "' . escape(w, ' .') . '"\ to\ word\ list'
-	exe 'amenu 1.6 PopUp.' . s:additem . ' :spellgood ' . w . '<CR>'
+	exe 'anoremenu 1.6 PopUp.' . s:additem . ' :spellgood ' . w . '<CR>'
 
 	let s:ignoreitem = 'ignore\ "' . escape(w, ' .') . '"'
-	exe 'amenu 1.7 PopUp.' . s:ignoreitem . ' :spellgood! ' . w . '<CR>'
+	exe 'anoremenu 1.7 PopUp.' . s:ignoreitem . ' :spellgood! ' . w . '<CR>'
 
-	amenu 1.8 PopUp.-SpellSep- :
+	anoremenu 1.8 PopUp.-SpellSep- :
       endif
     endif
   endfunc
@@ -938,7 +940,9 @@
     let s:changeitem = ''
   endfun
 
-  au! MenuPopup * call <SID>SpellPopup()
+  augroup SpellPopupMenu
+    au! MenuPopup * call <SID>SpellPopup()
+  augroup END
 endif
 
 " The GUI toolbar (for MS-Windows and GTK)
@@ -1013,9 +1017,9 @@
     tmenu ToolBar.FindPrev	Find Previous
     tmenu ToolBar.Replace		Find / Replace...
   endif
-  tmenu ToolBar.LoadSesn	Chose a session to load
+  tmenu ToolBar.LoadSesn	Choose a session to load
   tmenu ToolBar.SaveSesn	Save current session
-  tmenu ToolBar.RunScript	Chose a Vim Script to run
+  tmenu ToolBar.RunScript	Choose a Vim Script to run
   tmenu ToolBar.Make		Make current project (:make)
   tmenu ToolBar.RunCtags	Build tags in current directory tree (!ctags -R .)
   tmenu ToolBar.TagJump		Jump to tag under cursor
diff -Naur vim70.orig/runtime/plugin/matchparen.vim vim70/runtime/plugin/matchparen.vim
--- vim70.orig/runtime/plugin/matchparen.vim	2006-04-27 06:31:26.000000000 -0700
+++ vim70/runtime/plugin/matchparen.vim	2006-11-29 16:10:05.000000000 -0800
@@ -1,6 +1,6 @@
 " Vim plugin for showing matching parens
 " Maintainer:  Bram Moolenaar <Bram@vim.org>
-" Last Change: 2006 Apr 27
+" Last Change: 2006 Sep 09
 
 " Exit quickly when:
 " - this plugin was already loaded (or disabled)
@@ -44,7 +44,7 @@
   let before = 0
 
   let c = getline(c_lnum)[c_col - 1]
-  let plist = split(&matchpairs, ':\|,')
+  let plist = split(&matchpairs, '.\zs[:,]')
   let i = index(plist, c)
   if i < 0
     " not found, in Insert mode try character before the cursor
@@ -90,19 +90,19 @@
   " Find the match.  When it was just before the cursor move it there for a
   " moment.
   if before > 0
-    let save_cursor = getpos('.')
+    let save_cursor = winsaveview()
     call cursor(c_lnum, c_col - before)
   endif
 
   " When not in a string or comment ignore matches inside them.
   let s_skip ='synIDattr(synID(line("."), col("."), 0), "name") ' .
-	\ '=~?  "string\\|comment"'
+	\ '=~?  "string\\|character\\|singlequote\\|comment"'
   execute 'if' s_skip '| let s_skip = 0 | endif'
 
   let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline)
 
   if before > 0
-    call setpos('.', save_cursor)
+    call winrestview(save_cursor)
   endif
 
   " If a match is found setup match highlighting.
diff -Naur vim70.orig/runtime/scripts.vim vim70/runtime/scripts.vim
--- vim70.orig/runtime/scripts.vim	2006-03-28 11:30:49.000000000 -0800
+++ vim70/runtime/scripts.vim	2006-11-29 16:09:55.000000000 -0800
@@ -1,7 +1,7 @@
 " Vim support file to detect file types in scripts
 "
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last change:	2006 Mar 28
+" Last change:	2006 Jul 08
 
 " This file is called by an autocommand for every file that has just been
 " loaded into a buffer.  It checks if the type of file can be recognized by
@@ -54,6 +54,12 @@
     let s:name = substitute(s:line1, '^#!\s*\S*[/\\]\(\i\+\).*', '\1', '')
   endif
 
+  " tcl scripts may have #!/bin/sh in the first line and "exec wish" in the
+  " third line.  Suggested by Steven Atkinson.
+  if getline(3) =~ '^exec wish'
+    let s:name = 'wish'
+  endif
+
   " Bourne-like shell scripts: bash bash2 ksh ksh93 sh
   if s:name =~ '^\(bash\d*\|\|ksh\d*\|sh\)\>'
     call SetFileTypeSH(s:line1)	" defined in filetype.vim
diff -Naur vim70.orig/runtime/tutor/Makefile vim70/runtime/tutor/Makefile
--- vim70.orig/runtime/tutor/Makefile	2004-06-07 07:32:39.000000000 -0700
+++ vim70/runtime/tutor/Makefile	2006-11-29 16:10:05.000000000 -0800
@@ -2,8 +2,13 @@
 #
 # The Japanese tutor exists in three encodings.  Use the UTF-8 version as the
 # original and create the others with conversion.
+#
+# Similarly for Russian and Korean
 
-all: tutor.ja.sjis tutor.ja.euc tutor.ko.euc
+all: tutor.ja.sjis tutor.ja.euc \
+	tutor.ko.euc \
+	tutor.ru tutor.ru.cp1251 \
+	tutor.gr tutor.gr.cp737
 
 tutor.ja.sjis: tutor.ja.utf-8
 	nkf -WXs tutor.ja.utf-8 > tutor.ja.sjis
@@ -13,3 +18,15 @@
 
 tutor.ko.euc: tutor.ko.utf-8
 	iconv -f UTF-8 -t EUC-KR tutor.ko.utf-8 > tutor.ko.euc
+
+tutor.ru: tutor.ru.utf-8
+	iconv -f UTF-8 -t KOI8-R tutor.ru.utf-8 > tutor.ru
+
+tutor.ru.cp1251: tutor.ru.utf-8
+	iconv -f UTF-8 -t cp1251 tutor.ru.utf-8 > tutor.ru.cp1251
+
+tutor.gr: tutor.gr.utf-8
+	iconv -f UTF-8 -t ISO-8859-7 tutor.gr.utf-8 > tutor.gr
+
+tutor.gr.cp737: tutor.gr.utf-8
+	iconv -f UTF-8 -t cp737 tutor.gr.utf-8 > tutor.gr.cp737
diff -Naur vim70.orig/runtime/tutor/tutor.gr.utf-8 vim70/runtime/tutor/tutor.gr.utf-8
--- vim70.orig/runtime/tutor/tutor.gr.utf-8	1969-12-31 16:00:00.000000000 -0800
+++ vim70/runtime/tutor/tutor.gr.utf-8	2006-11-29 16:10:05.000000000 -0800
@@ -0,0 +1,815 @@
+===============================================================================
+=    Κ αλ ω σ ή ρ θ α τ ε    σ τ ο   V I M   T u t o r    -    Έκδοση 1.5     =
+===============================================================================
+
+     Ο Vim είναι ένας πανίσχυρος συντάκτης που έχει πολλές εντολές, πάρα
+     πολλές για να εξηγήσουμε σε μία περιήγηση όπως αυτή. Αυτή η περιήγηση
+     σχεδιάστηκε για να περιγράψει ικανοποιητικά τις εντολές που θα σας
+     κάνουν να χρησιμοποιείτε εύκολα τον Vim σαν έναν γενικής χρήσης συντάκτη.
+
+     Ο κατά προσέγγιση χρόνος που απαιτείται για να ολοκληρώσετε την περιήγηση
+     είναι 25-30 λεπτά, εξαρτώντας από το πόσο χρόνο θα ξοδέψετε για
+     πειραματισμούς.
+
+     Οι εντολές στα μαθήματα θα τροποποιήσουν το κείμενο. Δημιουργήστε ένα
+     αντίγραφο αυτού του αρχείου για να εξασκηθείτε (αν ξεκινήσατε το
+     "Vimtutor" αυτό είναι ήδη ένα αντίγραφο).
+
+     Είναι σημαντικό να θυμάστε ότι αυτή η περιήγηση είναι οργανωμένη έτσι
+     ώστε να διδάσκει μέσω της χρήσης. Αυτό σημαίνει ότι χρειάζεται να
+     εκτελείτε τις εντολές για να τις μάθετε σωστά. Αν διαβάζετε μόνο το
+     κείμενο, θα τις ξεχάσετε!
+
+     Τώρα, βεβαιωθείτε ότι το πλήκτρο Shift-Lock ΔΕΝ είναι πατημένο και
+     πατήστε το πλήκτρο j αρκετές φορές για να μετακινήσετε τον δρομέα έτσι
+     ώστε το Μάθημα 1.1 να γεμίσει πλήρως την οθόνη.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		      Μάθημα 1.1:  ΜΕΤΑΚΙΝΟΝΤΑΣ ΤΟΝ ΔΡΟΜΕΑ
+
+  ** Για να κινήσετε τον δρομέα, πατήστε τα πλήκτρα h,j,k,l όπως δείχνεται. **
+	     ^
+	     k	      Hint: Το πλήκτρο h είναι αριστερά και κινεί στ' αριστερά.
+       < h	 l >	    Το πλήκτρο l είναι δεξιά και κινεί στα δεξιά.
+	     j		    Το πλήκτρο j μοιάζει με βελάκι προς τα κάτω.
+	     v
+
+  1. Μετακινείστε τον δρομέα τριγύρω στην οθόνη μέχρι να νοιώθετε άνετα.
+
+  2. Κρατήστε πατημένο το κάτω πλήκτρο (j) μέχρι να επαναληφθεί.
+---> Τώρα ξέρετε πώς να μετακινηθείτε στο επόμενο μάθημα.
+
+  3. Χρησιμοποιώντας το κάτω πλήκτρο, μετακινηθείτε στο Μάθημα 1.2.
+
+Σημείωση: Αν αμφιβάλλετε για κάτι που πατήσατε, πατήστε <ESC> για να βρεθείτε
+	  στην Κανονική Κατάσταση. Μετά πατήστε ξανά την εντολή που θέλατε.
+
+Σημείωση: Τα πλήκτρα του δρομέα θα πρέπει επίσης να δουλεύουν. Αλλά με τα hjkl
+	  θα μπορείτε να κινηθείτε πολύ γρηγορότερα, μόλις τα συνηθίσετε.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		Μάθημα 1.2:  ΜΠΑΙΝΟΝΤΑΣ ΚΑΙ ΒΓΑΙΝΟΝΤΑΣ ΣΤΟΝ VIM
+
+  !! ΣΗΜΕΙΩΣΗ: Πριν εκτελέσετε κάποιο από τα βήματα, διαβάστε όλο το μάθημα!!
+
+  1. Πατήστε το πλήκτρο <ESC> (για να είστε σίγουρα στην Κανονική Κατάσταση).
+
+  2. Πληκτρολογήστε:		:q! <ENTER>.
+
+---> Αυτό εξέρχεται από τον συντάκτη ΧΩΡΙΣ να σώσει όποιες αλλαγές έχετε κάνει.
+     Αν θέλετε να σώσετε τις αλλαγές και να εξέρθετε πληκτρολογήστε:
+	      :wq <ENTER>
+
+  3. Όταν δείτε την προτροπή του φλοιού, πληκτρολογήστε την εντολή με την οποία
+     μπήκατε σε αυτήν την περιήγηση. Μπορεί να είναι:	vimtutor <ENTER>
+     Κανονικά θα χρησιμοποιούσατε:			vim tutor <ENTER>
+
+---> 'vim' σημαίνει εισαγωγή στον συντάκτη vim, 'tutor' είναι το αρχείο που
+     θέλουμε να διορθώσουμε.
+
+  4. Αν έχετε απομνημονεύσει αυτά τα βήματα και έχετε αυτοπεποίθηση, εκτελέστε
+     τα βήματα 1 έως 3 για να βγείτε και να μπείτε ξανά στον συντάκτη. Μετά
+     μετακινήστε τον δρομέα κάτω στο Μάθημα 1.3.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		   Μάθημα 1.3:  ΔΙΟΡΘΩΣΗ ΚΕΙΜΕΝΟΥ - ΔΙΑΓΡΑΦΗ
+
+   ** Όσο είστε στην Κανονική Κατάσταση πατήστε  x  για να διαγράψετε τον
+      χαρακτήρα κάτω από τον δρομέα. **
+
+  1. Μετακινείστε τον δρομέα στην παρακάτω γραμμή σημειωμένη με --->.
+
+  2. Για να διορθώσετε τα λάθη, κινείστε τον δρομέα μέχρι να είναι πάνω από
+     τον χαρακτήρα που θα διαγραφεί.
+
+  3. Πατήστε το πλήκτρο x για να διαγράψετε τον ανεπιθύμητο χαρακτήρα.
+
+  4. Επαναλάβετε τα βήματα 2 μέχρι 4 μέχρι η πρόταση να είναι σωστή.
+
+---> The ccow jumpedd ovverr thhe mooon.
+
+  5. Τώρα που η γραμμή είναι σωστή, πηγαίντε στο Μάθημα 1.4.
+
+ΣΗΜΕΙΩΣΗ: Καθώς διατρέχετε αυτήν την περιήγηση, προσπαθήστε να μην
+	  απομνημονεύετε, μαθαίνετε με τη χρήση.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		   Μάθημα 1.4: ΔΙΟΡΘΩΣΗ ΚΕΙΜΕΝΟΥ - ΠΑΡΕΜΒΟΛΗ
+
+ ** Όσο είστε σε Κανονική Κατάσταση πατήστε  i  για να παρεμβάλλετε κείμενο. **
+
+  1. Μετακινείστε τον δρομέα μέχρι την πρώτη γραμμή παρακάτω σημειωμένη με --->.
+
+  2. Για να κάνετε την πρώτη γραμμή ίδια με την δεύτερη, μετακινείστε τον
+     δρομέα πάνω στον πρώτο χαρακτήρα ΜΕΤΑ από όπου θα παρεμβληθεί το κείμενο.
+
+  3. Πατήστε το  i  και πληκτρολογήστε τις απαραίτητες προσθήκες.
+
+  4. Καθώς διορθώνετε κάθε λάθος πατήστε <ESC> για να επιστρέψετε στην
+     Κανονική Κατάσταση. Επαναλάβετε τα βήματα 2 μέχρι 4 για να διορθώσετε
+     την πρόταση.
+
+---> There is text misng this .
+---> There is some text missing from this line.
+
+  5. Όταν είστε άνετοι με την παρεμβολή κειμένου μετακινηθείτε στην
+     παρακάτω περίληψη.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			       ΜΑΘΗΜΑ 1 ΠΕΡΙΛΗΨΗ
+
+
+  1. Ο δρομέας κινείται χρησιμοποιώντας είτε τα πλήκτρα δρομέα ή τα hjkl.
+	 h (αριστέρα)	j (κάτω)	k (πάνω)	l (δεξιά)
+
+  2. Για να μπείτε στον Vim (από την προτροπή %) γράψτε:  vim ΑΡΧΕΙΟ <ENTER>
+
+  3. Για να βγείτε γράψτε:  <ESC>   :q!   <ENTER>   για απόρριψη των αλλαγών.
+		 Ή γράψτε:  <ESC>   :wq   <ENTER>   για αποθήκευση των αλλαγών.
+
+  4. Για να διαγράψετε έναν χαρακτήρα κάτω από τον δρομέα σε
+     Κανονική Κατάσταση πατήστε:  x
+
+  5. Για να εισάγετε κείμενο στον δρομέα όσο είστε σε Κανονική Κατάσταση γράψτε:
+	 i     πληκτρολογήστε το κείμενο	<ESC>
+
+ΣΗΜΕΙΩΣΗ: Πατώντας <ESC> θα τοποθετηθείτε στην Κανονική Κατάσταση ή θα
+	  ακυρώσετε μία ανεπιθύμητη και μερικώς ολοκληρωμένη εντολή.
+
+Τώρα συνεχίστε με το Μάθημα 2.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			 Μάθημα 2.1: ΕΝΤΟΛΕΣ ΔΙΑΓΡΑΦΗΣ
+
+	 ** Γράψτε  dw  για να διαγράψετε μέχρι το τέλος μίας λέξης. **
+
+  1. Πατήστε  <ESC>  για να βεβαιωθείτε ότι είστε στην Κανονική Κατάσταση.
+
+  2. Μετακινείστε τον δρομέα στην παρακάτω γραμμή σημειωμένη με --->.
+
+  3. Πηγαίνετε τον δρομέα στην αρχή της λέξης που πρέπει να διαγραφεί.
+
+  4. Γράψτε  dw  για να κάνετε την λέξη να εξαφανιστεί.
+
+ΣΗΜΕΙΩΣΗ: Τα γράμματα dw θα εμφανιστούν στην τελευταία γραμμή της οθόνης όσο
+	  τα πληκτρολογείτε. Αν γράψατε κάτι λάθος, πατήστε  <ESC>  και
+	  ξεκινήστε από την αρχή.
+
+---> There are a some words fun that don't belong paper in this sentence.
+
+  5. Επαναλάβετε τα βήματα 3 και 4 μέχρι η πρόταση να είναι σωστή και
+     πηγαίνετε στο Μάθημα 2.2.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		   Μάθημα 2.2: ΠΕΡΙΣΣΟΤΕΡΕΣ ΕΝΤΟΛΕΣ ΔΙΑΓΡΑΦΗΣ
+
+    ** Πληκτρολογήστε  d$  για να διαγράψετε μέχρι το τέλος της γραμμής. **
+
+  1. Πατήστε  <ESC>  για να βεβαιωθείτε ότι είστε στην Κανονική Κατάσταση.
+
+  2. Μετακινείστε τον δρομέα στην παρακάτω γραμμή σημειωμένη με --->.
+
+  3. Μετακινείστε τον δρομέα στο τέλος της σωστής γραμμής (ΜΕΤΑ την πρώτη . ).
+
+  4. Πατήστε   d$   για να διαγράψετε μέχρι το τέλος της γραμμής.
+
+---> Somebody typed the end of this line twice. end of this line twice.
+
+  5. Πηγαίνετε στο Μάθημα 2.3 για να καταλάβετε τι συμβαίνει.
+
+
+
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		   Μάθημα 2.3: ΠΕΡΙ ΕΝΤΟΛΩΝ ΚΑΙ ΑΝΤΙΚΕΙΜΕΝΩΝ
+
+
+Η μορφή της εντολής διαγραφής  d  είναι ως εξής:
+
+	 [αριθμός]   d   αντικείμενο	Ή	d   [αριθμός]   αντικείμενο
+  Όπου:
+    αριθμός - πόσες φορές θα εκτελεστεί η εντολή (προαιρετικό, εξ' ορισμού=1).
+    d - η εντολή της διαγραφής.
+    αντικείμενο - πάνω σε τι θα λειτουργήσει η εντολή (παρακάτω λίστα).
+
+  Μία μικρή λίστα από αντικείμενα:
+    w - από τον δρομέα μέχρι το τέλος της λέξης, περιλαμβάνοντας το διάστημα.
+    e - από τον δρομέα μέχρι το τέλος της λέξης, ΧΩΡΙΣ το διάστημα.
+    $ - από τον δρομέα μέχρι το τέλος της γραμμής.
+
+ΣΗΜΕΙΩΣΗ:  Για τους τύπους της περιπέτειας, πατώντας απλώς το αντικείμενο όσο
+	   είστε στην Κανονική Κατάσταση χωρίς κάποια εντολή θα μετακινήσετε
+	   τον δρομέα όπως καθορίζεται στην λίστα αντικειμένων.
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	       Μάθημα 2.4: ΜΙΑ ΕΞΑΙΡΕΣΗ ΣΤΗΝ 'ΕΝΤΟΛΗ-ΑΝΤΙΚΕΙΜΕΝΟ'
+
+	   ** Πληκτρολογήστε  dd  για να διαγράψετε όλη τη γραμμή. **
+
+  Εξαιτίας της συχνότητας της διαγραφής ολόκληρης γραμμής, οι σχεδιαστές
+  του Vim αποφάσισαν ότι θα ήταν ευκολότερο να γράφετε απλώς δύο d στη
+  σειρά για να διαγράψετε μία γραμμή.
+
+  1. Μετακινείστε τον δρομέα στη δεύτερη γραμμή της παρακάτω φράσης.
+  2. Γράψτε  dd  για να διαγράψετε τη γραμμή.
+  3. Τώρα μετακινηθείτε στην τέταρτη γραμμή.
+  4. Γράψτε  2dd  (θυμηθείτε  αριθμός-εντολή-αντικείμενο) για να
+     διαγράψετε δύο γραμμές.
+
+      1)  Roses are red,
+      2)  Mud is fun,
+      3)  Violets are blue,
+      4)  I have a car,
+      5)  Clocks tell time,
+      6)  Sugar is sweet
+      7)  And so are you.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			 Μάθημα 2.5: Η ΕΝΤΟΛΗ ΑΝΑΙΡΕΣΗΣ
+
+	    ** Πατήστε  u  για να αναιρέσετε τις τελευταίες εντολές,
+	       U για να διορθώσετε όλη τη γραμμή. **
+
+  1. Μετακινείστε τον δρομέα στην παρακάτω γραμμή σημειωμένη με ---> και
+     τοποθετήστε τον πάνω στο πρώτο λάθος.
+  2. Πατήστε  x  για να διαγράψετε τον πρώτο ανεπιθύμητο χαρακτήρα.
+  3. Τώρα πατήστε  u  για να αναιρέσετε την τελευταία εκτελεσμένη εντολή.
+  4. Αυτή τη φορά διορθώστε όλα τα λάθη στη γραμμή χρησιμοποιώντας την εντολή x.
+  5. Τώρα πατήστε ένα κεφαλαίο  U  για να επιστρέψετε τη γραμμή στην αρχική
+     της κατάσταση.
+  6. Τώρα πατήστε  u  μερικές φορές για να αναιρέσετε την  U  και
+     προηγούμενες εντολές.
+  7. Τώρα πατήστε CTRL-R (κρατώντας πατημένο το πλήκτρο CTRL καθώς πατάτε το R)
+     μερικές φορές για να επαναφέρετε τις εντολές (αναίρεση των αναιρέσεων).
+
+---> Fiix the errors oon thhis line and reeplace them witth undo.
+
+  8. Αυτές είναι πολύ χρήσιμες εντολές.  Τώρα πηγαίνετε στην
+     Περίληψη του Μαθήματος 2.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			       ΜΑΘΗΜΑ 2 ΠΕΡΙΛΗΨΗ
+
+
+  1. Για να διαγράψετε από τον δρομέα μέχρι το τέλος λέξης γράψτε:      dw
+
+  2. Για να διαγράψετε από τον δρομέα μέχρι το τέλος γραμμής γράψτε:    d$
+
+  3. Για να διαγράψετε ολόκληρη τη γραμμή γράψτε:    dd
+
+  4. Η μορφή για μία εντολή στην Κανονική Κατάσταση είναι:
+
+      [αριθμός]   εντολή   αντικείμενο    Ή    εντολή   [αριθμός]   αντικείμενο
+     όπου:
+       αριθμός - πόσες φορές να επαναληφθεί η εντολή
+       εντολή - τι να γίνει, όπως η  d  για διαγραφή
+       αντικείμενο - πάνω σε τι να ενεργήσει η εντολή, όπως  w  (λέξη),
+		     $ (τέλος της γραμμής), κτλ.
+
+  5. Για να αναιρέσετε προηγούμενες ενέργειες, πατήστε:        u   (πεζό u)
+     Για να αναιρέσετε όλες τις αλλαγές στη γραμμή, πατήστε:  U  (κεφαλαίο U)
+     Για να αναιρέσετε τις αναιρέσεις, πατήστε:               CTRL-R
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			Μάθημα 3.1: Η ΕΝΤΟΛΗ ΤΟΠΟΘΕΤΗΣΗΣ
+
+
+  ** Πατήστε  p  για να τοποθετήσετε την τελευταία διαγραφή μετά τον δρομέα.  **
+
+  1. Μετακινείστε τον δρομέα στην πρώτη γραμμή της παρακάτω ομάδας.
+
+  2. Πατήστε  dd  για να διαγράψετε τη γραμμή και να την αποθηκεύσετε σε
+     προσωρινή μνήμη του Vim.
+
+  3. Μετακινείστε τον δρομέα στη γραμμή ΠΑΝΩ από εκεί που θα πρέπει να πάει
+     η διαγραμμένη γραμμή.
+
+  4. Όσο είστε σε Κανονική Κατάσταση, πατήστε  p  για να βάλετε τη γραμμή.
+
+  5. Επαναλάβετε τα βήματα 2 έως 4 για να βάλετε όλες τις γραμμές στη
+     σωστή σειρά.
+
+     d) Can you learn too?
+     b) Violets are blue,
+     c) Intelligence is learned,
+     a) Roses are red,
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		      Μάθημα 3.2: Η ΕΝΤΟΛΗ ΑΝΤΙΚΑΤΑΣΤΑΣΗΣ
+
+
+    ** Πατήστε  r  και χαρακτήρα για να αλλάξετε αυτόν που είναι
+       κάτω από τον δρομέα. **
+
+  1. Μετακινείστε τον δρομέα στην πρώτη γραμμή παρακάτω σημειωμένη με --->.
+
+  2. Μετακινείστε τον δρομέα έτσι ώστε να είναι πάνω στο πρώτο λάθος.
+
+  3. Πατήστε  r  και μετά τον χαρακτήρα ο οποίος διορθώνει το λάθος.
+
+  4. Επαναλάβετε τα βήματα 2 και 3 μέχρι να είναι σωστή η πρώτη γραμμή.
+
+--->  Whan this lime was tuoed in, someone presswd some wrojg keys!
+--->  When this line was typed in, someone pressed some wrong keys!
+
+  5. Τώρα πηγαίνετε στο Μάθημα 3.2.
+
+ΣΗΜΕΙΩΣΗ: Να θυμάστε ότι πρέπει να μαθαίνετε με τη χρήση, και όχι με
+	  την απομνημόνευση.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			  Μάθημα 3.3: Η ΕΝΤΟΛΗ ΑΛΛΑΓΗΣ
+
+	   ** Για να αλλάξετε τμήμα ή όλη τη λέξη, πατήστε  cw  . **
+
+  1. Μετακινείστε τον δρομέα στην πρώτη γραμμή παρακάτω σημειωμένη με --->.
+
+  2. Τοποθετήστε τον δρομέα πάνω στο u της λέξης lubw.
+
+  3. Πατήστε  cw  και τη σωστή λέξη (στην περίπτωση αυτή, γράψτε  'ine'.)
+
+  4. Πατήστε <ESC> και πηγαίνετε στο επόμενο λάθος (στον πρώτο
+     χαρακτήρα προς αλλαγή).
+
+  5. Επαναλάβετε τα βήματα 3 και 4 μέχρις ότου η πρώτη πρόταση να είναι
+     ίδια με τη δεύτερη.
+
+---> This lubw has a few wptfd that mrrf changing usf the change command.
+---> This line has a few words that need changing using the change command.
+
+Παρατηρείστε ότι η  cw  όχι μόνο αντικαθιστάει τη λέξη, αλλά σας εισάγει
+επίσης σε παρεμβολή.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		     Μάθημα 3.4: ΠΕΡΙΣΣΟΤΕΡΕΣ ΑΛΛΑΓΕΣ ΜΕ c
+
+
+  ** Η εντολή αλλαγής χρησιμοποιείται με τα ίδια αντικείμενα της διαγραφής. **
+
+
+  1. Η εντολή αλλαγής δουλεύει με τον ίδιο τρόπο όπως η διαγραφή. Η μορφή είναι:
+
+       [αριθμός]   c   αντικείμενο     Ή     c   [αριθμός]   αντικείμενο
+
+  2. Τα αντικείμενα είναι πάλι τα ίδια, όπως w (λέξη), $ (τέλος γραμμής), κτλ.
+
+  3. Μετακινηθείτε στην πρώτη γραμμή παρακάτω σημειωμένη με --->.
+
+  4. Μετακινείστε τον δρομέα στο πρώτο λάθος.
+
+  5. Γράψτε  c$  για να κάνετε το υπόλοιπο της γραμμής ίδιο με τη δεύτερη
+     και πατήστε <ESC>.
+
+---> The end of this line needs some help to make it like the second.
+---> The end of this line needs to be corrected using the  c$  command.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			       ΜΑΘΗΜΑ 3 ΠΕΡΙΛΗΨΗ
+
+
+  1. Για να τοποθετήσετε κείμενο που μόλις έχει διαγραφεί, πατήστε  p .
+     Αυτό τοποθετεί το διαγραμμένο κείμενο ΜΕΤΑ τον δρομέα (αν διαγράφτηκε
+     γραμμή θα πάει μετά στη γραμμή κάτω από τον δρομέα.
+
+  2. Για να αντικαταστήσετε τον χαρακτήρα κάτω από τον δρομέα, πατήστε  r
+     και μετά τον χαρακτήρα που θα αντικαταστήσει τον αρχικό.
+
+  3. Η εντολή αλλαγής σας επιτρέπει να αλλάξετε το καθορισμένο αντικείμενο
+     από τον δρομέα μέχρι το τέλος του αντικείμενο. Π.χ. γράψτε  cw  για να
+     αλλάξετε από τον δρομέα μέχρι το τέλος της λέξης, c$ για να αλλάξετε
+     μέχρι το τέλος γραμμής.
+
+  4. Η μορφή για την αλλαγή είναι:
+
+	 [αριθμός]   c   αντικείμενο     Ή     c   [αριθμός]   αντικείμενο
+
+Τώρα συνεχίστε με το επόμενο μάθημα.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		     Μάθημα 4.1: ΘΕΣΗ ΚΑΙ ΚΑΤΑΣΤΑΣΗ ΑΡΧΕΙΟΥ
+
+
+ ** Πατήστε CTRL-g για να εμφανιστεί η θέση σας στο αρχείο και η κατάστασή του.
+    Πατήστε SHIFT-G για να πάτε σε μία γραμμή στο αρχείο. **
+
+  Σημείωση: Διαβάστε ολόκληρο το μάθημα πριν εκτελέσετε κάποιο από τα βήματα!!
+
+  1. Κρατήστε πατημένο το πλήκτρο Ctrl και πατήστε  g . Μία γραμμή κατάστασης
+     θα εμφανιστεί στο κάτω μέρος της σελίδας με το όνομα αρχείου και τη
+     γραμμή που είστε. Θυμηθείτε τον αριθμό γραμμής για το Βήμα 3.
+
+  2. Πατήστε shift-G για να μετακινηθείτε στο τέλος του αρχείου.
+
+  3. Πατήστε τον αριθμό της γραμμής που ήσασταν και μετά shift-G. Αυτό θα
+     σας επιστρέψει στη γραμμή που ήσασταν πριν πατήσετε για πρώτη φορά Ctrl-g.
+     (Όταν πληκτρολογείτε τους αριθμούς, ΔΕΝ θα εμφανίζονται στην οθόνη).
+
+  4. Αν νοιώθετε σίγουρος για αυτό, εκτελέστε τα βήματα 1 έως 3.
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			Μάθημα 4.2: Η ΕΝΤΟΛΗ ΑΝΑΖΗΤΗΣΗΣ
+
+
+	  ** Πατήστε   /   ακολουθούμενο από τη φράση που ψάχνετε. **
+
+  1. Σε Κανονική Κατάσταση πατήστε τον χαρακτήρα  / . Παρατηρήστε ότι αυτός και
+     ο δρομέας εμφανίζονται στο κάτω μέρος της οθόνης όπως με την εντολή  : .
+
+  2. Τώρα γράψτε 'errroor' <ENTER>. Αυτή είναι η λέξη που θέλετε να ψάξετε.
+
+  3. Για να ψάξετε ξανά για την ίδια φράση, πατήστε απλώς  n .
+     Για να ψάξετε την ίδια φράση στην αντίθετη κατεύθυνση, πατήστε  Shift-N .
+
+  4. Αν θέλετε να ψάξετε για μία φράση προς τα πίσω, χρησιμοποιήστε την εντολή  ?  αντί της  / .
+
+---> Όταν η αναζήτηση φτάσει στο τέλος του αρχείου θα συνεχίσει από την αρχή.
+
+  "errroor" is not the way to spell error;  errroor is an error.
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		   Μάθημα 4.3: ΕΥΡΕΣΗ ΤΑΙΡΙΑΣΤΩΝ ΠΑΡΕΝΘΕΣΕΩΝ
+
+
+	  ** Πατήστε   %   για να βρείτε την αντίστοιχη ), ], ή } . **
+
+  1. Τοποθετήστε τον δρομέα σε κάποια (, [, ή { στην παρακάτω γραμμή
+     σημειωμένη με --->.
+
+  2. Τώρα πατήστε τον χαρακτήρα  % .
+
+  3. Ο δρομέας θα πρέπει να είναι στην αντίστοιχη παρένθεση ή αγκύλη.
+
+  4. Πατήστε  %  για να μετακινήσετε τον δρομέα πίσω στην πρώτη αγκύλη
+    (του ζευγαριού).
+
+---> This ( is a test line with ('s, ['s ] and {'s } in it. ))
+
+ΣΗΜΕΙΩΣΗ: Αυτό είναι πολύ χρήσιμο στην αποσφαλμάτωση ενός προγράμματος
+	  με μη ταιριαστές παρενθέσεις!
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		    Μάθημα 4.4: ΕΝΑΣ ΤΡΟΠΟΣ ΓΙΑ ΑΛΛΑΓΗ ΛΑΘΩΝ
+
+
+       ** Γράψτε  :s/old/new/g  για να αλλάξετε το 'new' με το 'old'. **
+
+  1. Μετακινείστε τον δρομέα στην παρακάτω γραμμή σημειωμένη με --->.
+
+  2. Γράψτε  :s/thee/the <ENTER> . Σημειώστε ότι αυτή η εντολή αλλάζει μόνο
+     την πρώτη εμφάνιση στη γραμμή.
+
+  3. Τώρα γράψτε   :s/thee/the/g    εννοώντας γενική αντικατάσταση στη
+     γραμμή. Αυτό αλλάζει όλες τις εμφανίσεις επί της γραμμής.
+
+---> thee best time to see thee flowers is in thee spring.
+
+  4. Για να αλλάξετε κάθε εμφάνιση μίας συμβολοσειράς μεταξύ δύο γραμμών,
+     γράψτε   :#,#s/old/new/g   όπου #,# οι αριθμοί των δύο γραμμών.
+     Γράψτε   :%s/old/new/g     για να αλλάξετε κάθε εμφάνιση σε όλο το αρχείο.
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			       ΜΑΘΗΜΑ 4 ΠΕΡΙΛΗΨΗ
+
+
+  1. Το  Ctrl-g  εμφανίζει τη θέση σας στο αρχείο και την κατάστασή του.
+     Το  Shift-G  πηγαίνει στο τέλος του αρχείου. Ένας αριθμός γραμμής
+     ακολουθούμενος από  Shift-G  πηγαίνει σε εκείνη τη γραμμή.
+
+  2. Γράφοντας  /  ακολουθούμενο από μία φράση ψάχνει προς τα ΜΠΡΟΣΤΑ για
+     τη φράση. Γράφοντας  ?  ακολουθούμενο από μία φράση ψάχνει προς τα ΠΙΣΩ
+     για τη φράση. Μετά από μία αναζήτηση πατήστε  n  για να βρείτε την
+     επόμενη εμφάνιση προς την ίδια κατεύθυνση ή  Shift-N  για να ψάξετε
+     προς την αντίθετη κατεύθυνση.
+
+  3. Πατώντας  %  όσο ο δρομέας είναι πάνω σε μία (,),[,],{, ή }  εντοπίζει
+     το αντίστοιχο ταίρι του ζευγαριού.
+
+  4. Για αντικατάσταση με new του πρώτου old στη γραμμή γράψτε  :s/old/new
+     Για αντικατάσταση με new όλων των 'old' στη γραμμή γράψτε  :s/old/new/g
+     Για αντικατάσταση φράσεων μεταξύ δύο # γραμμών γράψτε      :#,#s/old/new/g
+     Για αντικατάσταση όλων των εμφανίσεων στο αρχείο γράψτε    :%s/old/new/g
+     Για ερώτηση επιβεβαίωσης κάθε φορά προσθέστε ένα 'c'       "%s/old/new/gc
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		  Μάθημα 5.1: ΠΩΣ ΕΚΤΕΛΩ ΜΙΑ ΕΞΩΤΕΡΙΚΗ ΕΝΤΟΛΗ
+
+
+** Γράψτε  :!  ακολουθούμενο από μία εξωτερική εντολή για να την εκτελέσετε. **
+
+  1. Πατήστε την οικεία εντολή  :  για να θέσετε τον δρομέα στο κάτω μέρος
+     της οθόνης. Αυτό σας επιτρέπει να δώσετε μία εντολή.
+
+  2. Τώρα πατήστε  το  !  (θαυμαστικό). Αυτό σας επιτρέπει να εκτελέσετε
+     οποιαδήποτε εξωτερική εντολή του φλοιού.
+
+  3. Σαν παράδειγμα γράψτε  ls  μετά από το ! και πατήστε <ENTER>. Αυτό θα
+     σας εμφανίσει μία λίστα του καταλόγου σας, ακριβώς σαν να ήσασταν στην
+     προτροπή του φλοιού. Ή χρησιμοποιήστε  :!dir  αν το ls δεν δουλεύει.
+
+---> Σημείωση: Είναι δυνατόν να εκτελέσετε οποιαδήποτε εξωτερική εντολή
+     με αυτόν τον τρόπο.
+
+---> Σημείωση: Όλες οι εντολές  :  πρέπει να τερματίζονται πατώντας το <ENTER>.
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		 Μάθημα 5.2: ΠΕΡΙΣΣΟΤΕΡΑ ΠΕΡΙ ΕΓΓΡΑΦΗΣ ΑΡΧΕΙΩΝ
+
+
+   ** Για να σώσετε τις αλλάγες που κάνατε στο αρχείο, γράψτε  :w ΑΡΧΕΙΟ.  **
+
+  1. Γράψτε  :!dir  ή  :!ls  για να πάρετε μία λίστα του καταλόγου σας.
+     Ήδη ξέρετε ότι πρέπει να πατήσετε <ENTER> μετά από αυτό.
+
+  2. Διαλέξτε ένα όνομα αρχείου που δεν υπάρχει ακόμα, όπως το TEST.
+
+  3. Τώρα γράψτε:  :w TEST  (όπου TEST είναι το όνομα αρχείου που διαλέξατε).
+
+  4. Αυτό σώζει όλο το αρχείο (vim Tutor) με το όνομα TEST. Για να το
+     επαληθεύσετε, γράψτε ξανά  :!dir για να δείτε τον κατάλογό σας.
+
+---> Σημειώστε ότι αν βγαίνατε από τον Vim και μπαίνατε ξανά με το όνομα
+     αρχείου TEST, το αρχείο θα ήταν ακριβές αντίγραφο του tutor όταν το σώσατε.
+
+  5. Τώρα διαγράψτε το αρχείο γράφοντας (MS-DOS):      :!del TEST
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		     Μάθημα 5.3: ΕΠΙΛΕΚΤΙΚΗ ΕΝΤΟΛΗ ΕΓΓΡΑΦΗΣ
+
+
+	  ** Για να σώσετε τμήμα του αρχείου, γράψτε  :#,# w ΑΡΧΕΙΟ **
+
+  1. Άλλη μια φορά, γράψτε  :!dir  ή  :!ls  για να πάρετε μία λίστα από τον
+     κατάλογό σας και διαλέξτε ένα κατάλληλο όνομα αρχείου όπως το TEST.
+
+  2. Μετακινείστε τον δρομέα στο πάνω μέρος αυτής της σελίδας και πατήστε
+     Ctrl-g  για να βρείτε τον αριθμό αυτής της γραμμής.
+     ΝΑ ΘΥΜΑΣΤΕ ΑΥΤΟΝ ΤΟΝ ΑΡΙΘΜΟ!
+
+  3. Τώρα πηγαίνετε στο κάτω μέρος της σελίδας και πατήστε  Ctrl-g  ξανά.
+     ΝΑ ΘΥΜΑΣΤΕ ΚΑΙ ΑΥΤΟΝ ΤΟΝ ΑΡΙΘΜΟ!
+
+  4. Για να σώσετε ΜΟΝΟ ένα τμήμα σε αρχείο, γράψτε   :#,# w TEST
+     όπου #,# οι δύο αριθμοί που απομνημονεύσατε (πάνω,κάτω) και TEST το
+     όνομα του αρχείου σας.
+
+  5. Ξανά, δείτε ότι το αρχείο είναι εκεί με την  :!dir αλλά ΜΗΝ το διαγράψετε.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		  Μάθημα 5.4: ΑΝΑΚΤΩΝΤΑΣ ΚΑΙ ΕΝΩΝΟΝΤΑΣ ΑΡΧΕΙΑ
+
+
+     ** Για να εισάγετε τα περιεχόμενα ενός αρχείου, γράψτε   :r ΑΡΧΕΙΟ **
+
+  1. Γράψτε  :!dir  για να βεβαιωθείτε ότι το TEST υπάρχει από πριν.
+
+  2. Τοποθετήστε τον δρομέα στο πάνω μέρος της σελίδας.
+
+ΣΗΜΕΙΩΣΗ:  Αφότου εκτελέσετε το Βήμα 3 θα δείτε το Μάθημα 5.3.
+	   Μετά κινηθείτε ΚΑΤΩ ξανά προς το μάθημα αυτό.
+
+  3. Τώρα ανακτήστε το αρχείο σας TEST χρησιμοποιώντας την εντολή  :r TEST
+     όπου TEST είναι το όνομα του αρχείου.
+
+ΣΗΜΕΙΩΣΗ:  Το αρχείο που ανακτάτε τοποθετείται ξεκινώντας εκεί που βρίσκεται
+	   ο δρομέας.
+
+  4. Για να επαληθεύσετε ότι το αρχείο ανακτήθηκε, πίσω τον δρομέα και
+     παρατηρήστε ότι υπάρχουν τώρα δύο αντίγραφα του Μαθήματος 5.3, το
+     αρχικό και η έκδοση του αρχείου.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			       ΜΑΘΗΜΑ 5 ΠΕΡΙΛΗΨΗ
+
+
+  1.  :!εντολή  εκτελεί μία εξωτερική εντολή.
+
+      Μερικά χρήσιμα παραδείγματα είναι (MS-DOS):
+      :!dir            - εμφάνιση λίστας ενός καταλόγου.
+      :!del ΑΡΧΕΙΟ     - διαγράφει το ΑΡΧΕΙΟ.
+
+  2.  :w ΑΡΧΕΙΟ   γράφει το τρέχων αρχείο του Vim στο δίσκο με όνομα ΑΡΧΕΙΟ.
+
+  3.  :#,#w ΑΡΧΕΙΟ   σώζει τις γραμμές από # μέχρι # στο ΑΡΧΕΙΟ.
+
+  4.  :r ΑΡΧΕΙΟ  ανακτεί το αρχείο δίσκου ΑΡΧΕΙΟ και το παρεμβάλλει μέσα
+      στο τρέχον αρχείο μετά από τη θέση του δρομέα.
+
+
+
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			Μάθημα 6.1: Η ΕΝΤΟΛΗ ΑΝΟΙΓΜΑΤΟΣ
+
+
+      ** Πατήστε  o  για να ανοίξετε μία γραμμή κάτω από τον δρομέα και να
+	 βρεθείτε σε Κατάσταση Κειμένου. **
+
+  1. Μετακινείστε τον δρομέα στην παρακάτω γραμμή σημειωμένη με --->.
+
+  2. Πατήστε  o (πεζό) για να ανοίξετε μία γραμμή ΚΑΤΩ από τον δρομέα και να
+     βρεθείτε σε Κατάσταση Κειμένου.
+
+  3. Τώρα αντιγράψτε τη σημειωμένη με ---> γραμμή  και πατήστε <ESC> για να
+     βγείτε από την Κατάσταση Κειμένου.
+
+---> After typing  o  the cursor is placed on the open line in Insert mode.
+
+  4. Για να ανοίξετε μία γραμμή ΠΑΝΩ από τον δρομέα, πατήστε απλά ένα κεφαλαίο
+     O, αντί για ένα πεζό  o.  Δοκιμάστε το στην παρακάτω γραμμή.
+Ανοίγετε γραμμή πάνω από αυτήν πατώντας Shift-O όσο ο δρομέας είναι στη γραμμή
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			 Μάθημα 6.2: Η ΕΝΤΟΛΗ ΠΡΟΣΘΗΚΗΣ
+
+	  ** Πατήστε   a   για να εισάγετε κείμενο ΜΕΤΑ τον δρομέα. **
+
+  1. Μετακινείστε τον δρομέα στο τέλος της πρώτης γραμμής παρακάτω
+     σημειωμένη με ---> πατώντας  $  στην Κανονική Κατάσταση.
+
+  2. Πατήστε ένα  a  (πεζό) για να προσθέσετε κείμενο ΜΕΤΑ από τον χαρακτήρα
+     που είναι κάτω από τον δρομέα.  (Το κεφαλαίο  A  προσθέτει στο τέλος
+     της γραμμής).
+
+Σημείωση: Αυτό αποφεύγει το πάτημα του  i , τον τελευταίο χαρακτήρα, το
+	  κείμενο της εισαγωγής, <ESC>, δρομέα-δεξιά, και τέλος, x, μόνο και
+	  μόνο για να προσθέσετε στο τέλος της γραμμής!
+
+  3. Συμπληρώστε τώρα την πρώτη γραμμή. Σημειώστε επίσης ότι η προσθήκη είναι
+     ακριβώς ίδια στην Κατάσταση Κειμένου με την Κατάσταση Εισαγωγής, εκτός
+     από τη θέση που εισάγεται το κείμενο.
+
+---> This line will allow you to practice
+---> This line will allow you to practice appending text to the end of a line.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		   Μάθημα 6.3: ΑΛΛΗ ΕΚΔΟΣΗ ΤΗΣ ΑΝΤΙΚΑΤΑΣΤΑΣΗΣ
+
+
+ ** Πατήστε κεφαλαίο  R  για να αλλάξετε περισσότερους από έναν χαρακτήρες. **
+
+  1. Μετακινείστε τον δρομέα στην πρώτη γραμμή παρακάτω σημειωμένη με --->.
+
+  2. Τοποθετήστε τον δρομέα στην αρχή της πρώτης λέξης που είναι διαφορετική
+     από τη δεύτερη γραμμή σημειωμένη με ---> (η λέξη 'last').
+
+  3. Πατήστε τώρα  R   και αλλάξτε το υπόλοιπο του κειμένου στην πρώτη γραμμή
+     γράφοντας πάνω από το παλιό κείμενο ώστε να κάνετε την πρώτη γραμμή ίδια
+     με τη δεύτερη.
+
+---> To make the first line the same as the last on this page use the keys.
+---> To make the first line the same as the second, type R and the new text.
+
+  4. Σημειώστε ότι όταν πατάτε <ESC> για να βγείτε, παραμένει οποιοδήποτε
+     αναλλοίωτο κείμενο.
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			  Μάθημα 6.4: ΡΥΘΜΙΣΗ ΕΠΙΛΟΓΗΣ
+
+
+   ** Ρυθμίστε μία επιλογή έτσι ώστε η αναζήτηση ή η αντικατάσταση να αγνοεί
+      τη διαφορά πεζών-κεφαλαίων **
+
+  1. Ψάξτε για 'ignore' εισάγοντας:
+     /ignore
+     Συνεχίστε αρκετές φορές πατώντας το πλήκτρο n.
+
+  2. Θέστε την επιλογή 'ic' (Ignore case) γράφοντας:
+     :set ic
+
+  3. Ψάξτε τώρα ξανά για 'ignore' πατώντας: n
+     Συνεχίστε την αναζήτηση μερικές ακόμα φορές πατώντας το πλήκτρο n
+
+  4. Θέστε τις επιλογές 'hlsearch' και 'incsearch':
+     :set hls is
+
+  5. Εισάγετε τώρα ξανά την εντολή αναζήτησης, και δείτε τι συμβαίνει
+     /ignore
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			       ΜΑΘΗΜΑ 6 ΠΕΡΙΛΗΨΗ
+
+
+  1. Πατώντας  o  ανοίγει μία γραμμή ΚΑΤΩ από τον δρομέα και τοποθετεί τον
+     δρομέα στην ανοιχτή γραμμή σε Κατάσταση Κειμένου.
+
+  2. Πατήστε  a  για να εισάγετε κείμενο ΜΕΤΑ τον χαρακτήρα στον οποίο είναι
+     ο δρομέας. Πατώντας κεφαλαίο  A  αυτόματα προσθέτει κείμενο στο τέλος
+     της γραμμής.
+
+  3. Πατώντας κεφαλαίο  R  εισέρχεται στην Κατάσταη Αντικατάστασης μέχρι να
+     πατηθεί το <ESC> και να εξέλθει.
+
+  4. Γράφοντας ":set xxx" ρυθμίζει την επιλογή "xxx".
+
+
+
+
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		       ΜΑΘΗΜΑ 7: ON-LINE ΕΝΤΟΛΕΣ ΒΟΗΘΕΙΑΣ
+
+
+		** Χρησιμοποιήστε το on-line σύστημα βοήθειας **
+
+  Ο Vim έχει ένα περιεκτικό on-line σύστημα βοήθειας. Για να ξεκινήσει,
+  δοκιμάστε κάποιο από τα τρία:
+	- πατήστε το πλήκτρο <HELP> (αν έχετε κάποιο)
+	- πατήστε το πλήκτρο <F1> (αν έχετε κάποιο)
+	- γράψτε   :help <ENTER>
+
+  Γράψτε  :q <ENTER>   για να κλείσετε το παράθυρο της βοήθειας.
+
+  Μπορείτε να βρείτε βοήθεια πάνω σε κάθε αντικείμενο, δίνοντας μία παράμετρο
+  στην εντολή ":help".  Δοκιμάστε αυτά (μην ξεχνάτε να πατάτε <ENTER>):
+
+	:help w
+	:help c_<T
+	:help insert-index
+	:help user-manual
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		  ΜΑΘΗΜΑ 8: ΔΗΜΙΟΥΡΓΗΣΤΕ ΕΝΑ SCRIPT ΕΚΚΙΝΗΣΗΣ
+
+		   ** Ενεργοποιήστε χαρακτηριστικά του Vim **
+
+  Ο Vim έχει πολλά περισσότερα χαρακτηριστικά απ' ό,τι ο Vi, αλλά τα
+  περισσότερα είναι αρχικά απενεργοποιημένα. Για να αρχίσετε να χρησιμοποιείτε
+  περισσότερα χαρακτηριστικά πρέπει να φτιάξετε ένα αρχείο "vimrc".
+
+  1. Αρχίστε διορθώνοντας το αρχείο "vimrc", αυτό εξαρτάται από το σύστημά σας:
+	:edit ~/.vimrc               για Unix
+	:edit $VIM/_vimrc            για MS-Windows
+
+  2. Τώρα εισάγετε το κείμενο παραδείγματος για αρχείο "vimrc":
+	:read $VIMRUNTIME/vimrc_example.vim
+
+  3. Γράψτε το αρχείο με την:
+	:write
+
+  Την επόμενη φορά που θα ξεκινήσετε τον Vim θα χρησιμοποιήσει φωτισμό
+  σύνταξης.  Μπορείτε να προσθέσετε όλες τις προτιμώμενες επιλογές σ' αυτό
+  το αρχείο "vimrc".
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+  Εδώ ολοκληρώνεται το Vim Tutor. Σκοπός του ήταν να δώσει μία σύντομη
+  περίληψη του συντάκτη Vim, τουλάχιστον τόση ώστε να σας επιτρέψει να
+  χρησιμοποιήσετε τον συντάκτη αρκετά εύκολα. Απέχει πολύ από μία
+  ολοκληρωμένη παρουσίαση καθώς ο Vim έχει πάρα πολλές εντολές. Διαβάστε
+  κατόπιν το εγχειρίδιο χρήσης:
+	":help user-manual".
+
+  Για περαιτέρω διάβασμα και μελέτη, συστήνεται αυτό το βιβλίο:
+	Vim - Vi Improved - by Steve Oualline
+	Publisher: New Riders
+	Το πρώτο βιβλίο πλήρως αφιερωμένο στον Vim.
+	Ιδιαίτερα χρήσιμο για αρχάριους.
+	Υπάρχουν πολλά παραδείγματα και εικόνες.
+	Δείτε την http://iccf-holland.org/click5.html
+
+  Αυτό το βιβλίο είναι παλιότερο και περισσότερο για τον Vi παρά για τον Vim,
+  αλλά επίσης συνιστώμενο:
+	Learning the Vi Editor - by Linda Lamb
+	Publisher: O'Reilly & Associates Inc.
+	Είναι ένα καλό βιβλίο για να μάθετε σχεδόν τα πάντα που θέλετε
+	να κάνετε με τον Vi.
+	Η έκτη έκδοση περιέχει ακόμα πληροφορίες για τον Vim.
+
+  Αυτή η περιήγηση γράφτηκε από τους Michael C. Pierce και Robert K. Ware,
+  Colorado School of Mines χρησιμοποιώντας ιδέες από τον Charles Smith,
+  Colorado State University.  E-mail: bware@mines.colorado.edu.
+
+  Προσαρμογή για τον Vim από τον Bram Moolenaar.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff -Naur vim70.orig/runtime/tutor/tutor.ru.utf-8 vim70/runtime/tutor/tutor.ru.utf-8
--- vim70.orig/runtime/tutor/tutor.ru.utf-8	1969-12-31 16:00:00.000000000 -0800
+++ vim70/runtime/tutor/tutor.ru.utf-8	2006-11-29 16:10:01.000000000 -0800
@@ -0,0 +1,834 @@
+===============================================================================
+=    Д о б р о   п о ж а л о в а т ь   в   у ч е б н и к   VIM  -  Версия 1.5 =
+===============================================================================
+     Vim --- это очень мощный редактор, имеющий множество команд, слишком
+     много для того, чтобы их все можно было описать в таком учебнике, как
+     этот. Этот учебник призван объяснить достаточное число команд для того,
+     чтобы Вы могли с легкостью использовать Vim в качестве редактора общего
+     назначения.
+
+     Вам потребуется приблизительно 25-30 минут на освоение данного учебника в
+     зависимости от того, сколько времени Вы потратите на эксперименты.
+
+     Команды в уроках будут модифицировать текст. Создайте копию этого файла,
+     чтобы попрактиковаться на ней (если Вы запустили "vimtutor", то это уже
+     копия).
+
+     Важно помнить, что этот учебник предназначен для обучения в процессе
+     использования. Это означает, что Вы должны запускать команды для того,
+     чтобы как следует их изучить. Если Вы просто прочитаете текст, то
+     забудете команды!
+
+     Теперь убедитесь в том, что клавиша CapsLock не включена и нажмите
+     клавишу   j   несколько раз, так, чтобы Урок 1.1 полностью поместился на
+     экране.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			Урок 1.1:  ПЕРЕМЕЩЕНИЕ КУРСОРА
+
+** Для перемещения курсора нажмите клавиши h,j,k,l так, как показано ниже. **
+	     ^
+	     k		Советы:	Клавиша h находится слева и перемещает влево.
+       < h	 l >		Клавиша l находится справа и перемещает вправо.
+	     j			Клавиша j похожа на стрелку `вниз'.
+	     v
+  1. Подвигайте курсор по экрану, пока не почувствуете себя уверенно.
+
+  2. Надавите клавишу `вниз' (j) пока она не начнет повторяться.
+---> Теперь Вы знаете, как перейти к следующему уроку.
+
+  3. Используя клавишу `вниз' перейдите к Уроку 1.2.
+
+Замечание: Если вы пока не уверены в том, что набираете, нажмите <ESC> для
+	   перехода в обычный режим (Normal mode). После этого перенаберите
+	   требуемую команду.
+
+Замечание: Обычные клавиши управления курсором (стрелки) также должны
+	   работать. Однако, клавиши hjkl позволят Вам перемещаться
+	   значительно быстрее, как только Вы научитесь ими пользоваться.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		  Урок 1.2: ЗАПУСК И ЗАВЕРШЕНИЕ РАБОТЫ С VIM
+
+!! ВНИМАНИЕ! Прежде, чем выполнять любой из описанных ниже шагов, прочтите
+			       урок целиком !!
+
+  1. Нажмите клавишу <ESC> (для того, чтобы удостовериться, что Вы в обычном
+     режиме (Normal mode)).
+
+  2. Наберите:			:q! <ENTER>.
+
+---> Это позволит Вам выйти из редактора БЕЗ СОХРАНЕНИЯ любых сделанных
+     изменений. Если Вы хотите сохранить изменения и выйти:
+				:wq  <ENTER>
+
+  3. Когда Вы увидите приглашение командной оболочки, наберите команду,
+     которая привела Вас в этот учебник. Это может быть
+				vimtutor ru <ENTER>
+     Обычно можно использовать:	vim tutor.ru <ENTER>
+
+---> 'vim' позволяет запустить редактор vim, 'tutor.ru' --- это файл, который
+     Вы будете редактировать.
+
+  4. Если Вы уверены в том, что запомнили эти шаги, выполните шаги от 1 до 3
+     чтобы выйти снова запустить редактор. Затем переместите курсор вниз к
+     Уроку 1.3.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		  Урок 1.3: РЕДАКТИРОВАНИЕ ТЕКСТА - УДАЛЕНИЕ
+
+
+** Находясь в обычном режиме нажмите x, чтобы удалить символ под курсором. **
+
+  1. Переместите курсор к строке внизу, помеченной --->.
+
+  2. Для исправления ошибок, переместите курсор, пока он не окажется над
+     удаляемым символом.
+
+  3. Нажмите клавишу x для удаления требуемого символа.
+
+  4. Повторите шаги 2--4 пока строка не будет исправлена.
+
+---> От тттопота копытт пппыль ппо ппполю леттитт.
+
+  5. Теперь, когда строка откорректирована, переходите к уроку 1.4.
+
+ЗАМЕЧАНИЕ: В ходе освоения этого учебника не пытайтесь запоминать, учите
+	   в процессе использования.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		  Урок 1.4: РЕДАКТИРОВАНИЕ ТЕКСТА - ВСТАВКА
+
+
+ ** Находясь в обычном режиме (Normal mode), нажмите i для вставки текста. **
+
+  1. Переместите курсор к первой строке внизу, помеченной --->.
+
+  2. Для того, чтобы сделать первую строку идентичной второй, поместите
+     курсор на символ ПЕРЕД которым следует вставить текст.
+
+  3. Нажмите i и наберите требуемые добавления.
+
+  4. После исправления всех ошибок нажмите <ESC> для возврата в обычный режим.
+     Повторите шаги 2--4, пока фраза не будет исправлена полностью.
+
+---> Часть текста в строке беследно .
+---> Часть текста в этой строке бесследно пропала.
+
+  5. Когда освоите вставку текста, переходите дальше к Резюме.
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+				РЕЗЮМЕ УРОКА 1
+
+  1. Курсор перемещается либо клавишами со стрелками, либо клавишами hjkl.
+	 h (влево)	j (вниз)       k (вверх)	    l (вправо)
+
+  2. Для запуска Vim (из приглашения % командной оболочки) наберите:
+     vim ИМЯ_ФАЙЛА <ENTER>
+
+  3. Для завершения работы с Vim наберите:
+     <ESC>   :q!	 <ENTER>  чтобы отказаться от сохранения изменений.
+     Или наберите:
+     <ESC>   :wq	 <ENTER>  чтобы сохранить изменения.
+
+  4. Для удаления символа под курсором в обычном режиме, наберите: x
+
+  5. Чтобы вставить текст перед курсором в обычном режиме, наберите:
+	 i     вводите текст	<ESC>
+
+ЗАМЕЧАНИЕ: Нажатие <ESC> переместит Вас в обычный режим (Normal mode) либо
+	   прервет нежелательную и частично завершенную команду.
+
+Теперь переходим к Уроку 2.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			  Урок 2.1: КОМАНДЫ УДАЛЕНИЯ
+
+
+	** Наберите dw для удаления участка текста до конца слова. **
+
+  1. Нажмите <ESC>, чтобы перейти в обычный режим.
+
+  2. Переместите курсор вниз, к строке, помеченной --->.
+
+  3. Переместите курсор в начало слова, которое следует удалить.
+
+  4. Наберите  dw , чтобы удалить это слово.
+
+ЗАМЕЧАНИЕ: Во время набора буквы dw появятся в последней строке экрана. Если
+	   Вы что-то наберете неправильно, нажмите <ESC> и начните сначала.
+
+---> Несколько слов рафинад в этом предложении автокран излишни.
+
+  5. Повторите шаги 3 и 4, пока не исправите все ошибки и переходите к
+     Уроку 2.2.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		  Урок 2.2: ДОПОЛНИТЕЛЬНЫЕ КОМАНДЫ УДАЛЕНИЯ
+
+
+	    ** Наберите d$ для удаления текста до конца строки. **
+
+  1. Нажмите <ESC>, чтобы перейти в обычный режим.
+
+  2. Переместите курсор вниз, к строке, помеченной --->.
+
+  3. Переместите курсор к концу правильной строки (ПОСЛЕ первой . ).
+
+  4. Чтобы удалить остаток строки, наберите  d$ .
+
+---> Кто-то набрал окончание этой строки дважды. окончание этой строки дважды.
+
+
+  5.Чтобы лучше разобраться в этом, переходите к Уроку 2.3.
+
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			 Урок 2.3: КОМАНДЫ И ОБЪЕКТЫ
+
+
+  Формат команды `удаление' d таков:
+
+	 [число]   d	объект	    ИЛИ	     d	 [число]   объект
+  Здесь:
+    число  - сколько раз исполнить команду (необязательно, по умолчанию=1).
+    d      - команда удаления.
+    объект - с чем команда должна быть выполнена (перечислено ниже).
+
+  Краткий список объектов:
+    w - от курсора до конца слова, включая завершающий пробел.
+    e - от курсора до конца слова, НЕ включая завершающий пробел.
+    $ - от курсора до конца строки.
+    ^ - от курсора до начала строки.
+
+ЗАМЕЧАНИЕ: Простое нажатие на символ объекта в обычном режиме (Normal mode)
+	   без дополнительных команд передвинет курсор так, как указано в
+	   списке объектов.
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	       Урок 2.4: ИСКЛЮЧЕНИЕ ИЗ ПРАВИЛА `КОМАНДА-ОБЪЕКТ'
+
+
+		 ** Наберите dd для удаления всей строки. **
+
+  Вследствие частого применения операции удаления всей строки, разработчики
+  Vim решили, что для этого проще всего просто набрать d дважды.
+
+  1. Переместите курсор вниз, ко второй строке фразы.
+  2. Наберите dd для удаления строки.
+  3. Теперь переместитесь к четвертой строке.
+  4. Наберите 2dd (вспомните правило `число-команда-объект'), чтобы удалить
+     две строки.
+
+      1)  Летом я хожу на стадион,
+      2)  О, как внезапно кончился диван!
+      3)  Я болею за ``Зенит'', ``Зенит'' --- чемпион!
+      4)  Печально я гляжу на наше поколение!
+      5)  Его грядущее иль пусто иль темно...
+      6)  Я сижу на скамейке в ложе `Б'
+      7)  И играю на большой жестяной трубе.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			  Урок 2.5: КОМАНДА `ОТКАТ'
+
+
+  ** Нажмите u	для отмены результата работы предыдущей команды, U для отмены
+			исправлений во всей строке. **
+
+  1. Переместите курсор вниз, к строке, помеченной ---> и установите его на
+     первую ошибку.
+  2. Нажмите x для удаления первого неправильного символа.
+  3. Теперь нажмите u для отмены (отката) последней выполненной команды.
+  4. Исправьте все ошибки в строке, используя команду x .
+  5. Теперь нажмите заглавную U для того, чтобы вернуть всю строку в исходное
+     состояние.
+  6. Нажмите u несколько раз для отмены команды U и предыдущих команд.
+  7. Нажмите теперь CTRL-R (удерживайте клавишу CTRL нажатой в момент нажатия
+  R)     несколько раз для возврата команд (откат отката).
+
+---> Испрравьте оошибки в этойй строке и вернитте их сс помощьью `отката'.
+
+  8. Это были очень полезные команды. Далее переходите к Резюме Урока 2.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+				РЕЗЮМЕ УРОКА 2
+
+
+  1. Для удаления текста от курсора до конца слова наберите:    dw
+
+  2. Для удаления текста от курсора до конца строки наберите:    d$
+
+  3. Для удаления всей строки наберите:    dd
+
+  4. Формат команды в обычном режиме имеет вид:
+
+       [число]   команда   объект     ИЛИ     команда	[число]   объект
+     где:
+       число   - сколько раз повторить выполнение команды
+       команда - что выполнить, например d для удаления
+       объект  - на что должна воздействовать команда, например w (слово),
+		$ (до конца строки), и т.д.
+
+  5. Для отмены (отката) предшествующих действий наберите:  u (строчная u)
+     Для отмены (отката) всех изменений в строке наберите:  U (прописная U)
+     Для отмены отката наберите:  CTRL-R
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			  Урок 3.1: КОМАНДА ВСТАВКИ
+
+
+   ** Наберите p для вставки последнего удаленного текста после курсора. **
+
+  1. Переместите курсор вниз к последней строке из набора.
+
+  2. Наберите dd для удаления строки и ее сохранения в буфере Vim'а.
+
+  3. Переместите курсор к строке НАД тем местом, куда следует вставить
+     удаленную строку.
+
+  4. Находясь в обычном режиме наберите p для замены строки.
+
+  5. Повторите шаги 2--4, пока не расставите все строки в нужном порядке.
+
+     г) И лучше выдумать не мог.
+     б) Когда не в шутку занемог,
+     в) Он уважать себя заставил
+     а) Мой дядя самых честных правил
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		       Урок 3.2: КОМАНДА ЗАМЕНЫ
+
+
+	  ** Наберите r и символ, заменяющий символ под курсором. **
+
+  1. Переместите курсор вниз, к строке, помеченной --->.
+
+  2. Установите курсор так, чтобы он находился над первой ошибкой.
+
+  3. Наберите r	и затем символ, исправляющий ошибку.
+
+  4. Повторите шаги 2 и 3, пока первая строка не будет исправлена.
+
+--->  В момегт набтра этой чтроки кое0кто с трудом попвдал по клваишам!
+--->  В момент набора этой строки кое-кто с трудом попадал по клавишам!
+
+  5. Теперь переходите к Уроку 3.2.
+
+ЗАМЕЧАНИЕ: Помните, что вы должны учиться в процессе работы, а не просто
+	   запоминая.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			 Урок 3.3: КОМАНДА ИЗМЕНЕНИЯ
+
+
+		** Для изменения части слова наберите cw . **
+
+  1. Переместите курсор вниз, к строке, помеченной --->.
+
+  2. Расположите курсор над буквой `o' в слове `сола'.
+
+  3. Наберите cw и исправьте слово (в данном случае, наберите `лов'.)
+
+  4. Нажмите <ESC> и переходите к следующей ошибке (к первому символу, который
+     надо изменить.)
+
+  5. Повторите шаги 3--4 пока первое предложение не станет идентичным второму.
+
+---> Несколько сола в эьгц строке тпгшцбь редалзкуюиесвх.
+---> Несколько слов в этой строке требуют редактирования.
+
+Обратите внимание, что cw не только заменяет слово, но и переводит вас в режим
+вставки.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		  Урок 3.4: ПРОДОЛЖАЕМ ИЗМЕНЯТЬ С КОМАНДОЙ c
+
+
+** Команда замены используется с теми же объектами, что и команда удаления. **
+
+  1. Команда изменения применяется таким же образом, как и команда удаления.
+     Ее формат таков:
+
+       [число]   c   объект	   ИЛИ	    c	[число]   объект
+
+  2. Объекты также совпадают: w (слово), $ (конец строки) и т.п.
+
+  3. Переместите курсор вниз, к строке, помеченной --->.
+
+  4. Перейдите к первой ошибке.
+
+  5. Наберите c$ и отредактируйте первую строку так, чтобы она совпадала со
+     второй, после чего нажмите <ESC>.
+
+---> Конец этой строки нуждается в помощи, чтобы стать похожим на второй.
+---> Конец этой строки нуждается в помощи команды c$ .
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+				РЕЗЮМЕ УРОКА 3
+
+
+  1. Для вставки текста, который только что был удален, наберите p . Эта
+     команда вставит удаленный текст ПОСЛЕ курсора (если была удалена строка,
+     то она будет помещена в строке под курсором).
+
+  2. Для замены символа под курсором наберите r и затем заменяющий символ.
+
+  3. Команда изменения позволяет Вам изменить указанный объект от курсора до
+     конца этого объекта. Например, наберите cw для замены от курсора до
+     конца слова, c$ для изменения до конца строки.
+
+  4. Формат команды изменения таков:
+
+	 [число]   c	объект	      ИЛИ	c   [число]   объект
+
+Теперь отправляйтесь к следующему уроку.
+
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	      Урок 4.1: ИНФОРМАЦИЯ О ФАЙЛЕ И РАСПОЛОЖЕНИЕ В НЕМ
+
+
+ ** Наберите CTRL-g чтобы увидеть Ваше месторасположение в файле и информацию
+				    о нем.
+	Наберите SHIFT-G для перемещения к заданной строке в файле. **
+
+  Замечание: Прочитайте весь урок прежде чем выполнять любые команды!!
+
+  1. Удерживая клавишу Ctrl нажмите g . Внизу экрана появится строка статуса с
+     именем файла и номером строки, в которой Вы находитесь. Запомните номер
+     строки, он потребуется на Шаге 3.
+
+  2. Нажмите shift-G для перемещения к концу файла.
+
+  3. Наберите номер строки, в которой вы находились и затем shift-G. Это
+     вернет Вас к строке, в которой Вы были, когда в первый раз нажали Ctrl-g.
+     (Когда Вы будете набирать цифры, они НЕ отобразятся на экране.)
+
+  4. Если Вы запомнили все вышесказанное, выполните шаги 1--3.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			   Урок 4.2: КОМАНДА ПОИСКА
+
+	      ** Наберите  /  и затем введите искомую фразу. **
+
+  1. В обычном режиме (Normal mode) наберите символ  / . Обратите внимание,
+     что он вместе с курсором появится внизу экрана, как это происходит с
+     командой :	.
+
+  2. Теперь наберите 'ошшшибка' <ENTER>. Это то слово, которое Вы будете
+     искать.
+
+  3. Для того, чтобы повторить поиск, просто нажмите n .
+     Для поиска этой фразы в обратном направлении, нажмите Shift-N .
+
+  4. Если Вы желаете сразу искать в обратном направлении, используйте
+     команду ? вместо / .
+
+---> Когда Вы при поиске достигнете конца файла, поиск будет продолжен с
+     начала.
+
+  "ошшшибка" это не способ произнесения слова `ошибка';  ошшшибка это ошибка.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			Урок 4.3: ПОИСК ПАРНЫХ СКОБОК
+
+
+		** Наберите % для поиска парных ),] или } . **
+
+  1. Поместите курсор над любой из (, [ или { в строке внизу, помеченной --->.
+
+  2. Теперь наберите символ % .
+
+  3. Курсор должен перескочить на парную скобку.
+
+  4. Наберите % для возврата курсора назад к первой скобке.
+
+---> Это ( строка, содержащая такие (, такие [ ] и такие { } скобки. ))
+
+Замечание: Это очень удобно при отладке программ с пропущенными скобками!
+
+
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		      Урок 4.4: СПОСОБ ИСПРАВЛЕНИЯ ОШИБОК
+
+
+	 ** Наберите :s/было/стало/g для замены 'было' на 'стало'. **
+
+  1. Переместите курсор вниз, к строке, помеченной --->.
+
+  2. Наберите :s/уводю/увожу <ENTER> . Обратите внимание на то, что эта команда
+     заменит только первое найденное вхождение в строке.
+
+  3. Теперь наберите :s/уводю/увожу/g , означающее подстановку глобально во
+     всей строке. Это заменит все найденные в строке вхождения.
+
+---> Я уводю к отверженным селеньям, я уводю сквозь вековечный стон, я уводю к
+     забытым поколеньям.
+
+  4. Для замены всех вхождений последовательности символов между двумя
+     строками,
+     наберите :#,#s/было/стало/g  где #,# --- номера этих строк.
+     Наберите :%s/было/стало/g    для замены всех вхождений во всем файле.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+				РЕЗЮМЕ УРОКА 4
+  1. Ctrl-g показывает ваше положение в файле и информацию о нем.
+     Shift-G перемещает Вас в конец файла. Номер, за которым следует Shift-G
+     позволяет перейти к строке с этим номером.
+
+  2. Нажатие / и затем ввод строки позволяет произвести поиск этой строки
+     ВПЕРЕД по тексту.
+     Нажатие ? и затем ввод строки позволяет произвести поиск этой строки
+     НАЗАД по тексту.
+     После поиска наберите n для перехода к следующему вхождению искомой
+     строки в том же направлении или Shift-N для перехода в противоположном
+     направлении.
+
+  3. Нажатие % , когда курсор находится на (,),[,],{, или } позволяет найти
+     парную скобку.
+
+  4. Для подстановки `стало' вместо первого `было' в строке, наберите
+     :s/old/new
+     Для подстановки `стало' вместо всех `было' в строке, наберите
+     :s/old/new/g
+     Для замены в интервале между двумя строками, наберите
+     :#,#s/old/new/g
+     Для замены всех вхождений `было' на `стало' в файле, наберите
+     :%s/old/new/g
+     Чтобы редактор каждый раз запрашивал подтверждение, добавьте 'c'
+     :%s/old/new/gc
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		   Урок 5.1: КАК ВЫПОЛНИТЬ ВНЕШНЮЮ КОМАНДУ
+
+
+    ** Наберите :! и затем внешнюю команду, которую следует выполнить. **
+
+  1. Наберите уже знакомую Вам команду : для установки курсора в командную
+     строку редактора. Это позволит Вам ввести команду.
+
+  2. Теперь наберите символ ! (восклицательный знак). Теперь можно исполнить
+     внешнюю команду, используя командную оболочку.
+
+  3. Для примера наберите ls после ! и нажмите <ENTER>. Эта команда выведет
+     список файлов в текущем каталоге, точно также, как если бы Вы ввели эту
+     команду в приглашении оболочки. Или попробуйте :!dir , если предыдущая
+     команда не сработала.
+
+---> Замечание: Таким способом можно выполнить любую внешнюю команду.
+
+---> Замечание: Все команды, начинающиеся с : , должны завершаться нажатием
+     <ENTER>.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			 Урок 5.2: КАК ЗАПИСАТЬ ФАЙЛ
+
+
+** Для сохранения изменений, произведенных в файле, наберите :w ИМЯ_ФАЙЛА. **
+
+  1. Наберите :!dir или :!ls для получения списка файлов в текущем каталоге.
+     Как Вам уже известно, Вы должны нажать <ENTER> после ввода этих команд.
+
+  2. Придумайте название для файла, которое еще не существует, например TEST.
+
+  3. Теперь наберите :w TEST (где TEST --- это имя файла, придуманное Вами.)
+
+  4. Эта команда сохранит весь файл (Учебник по Vim) под именем TEST. Чтобы
+     удостовериться в этом, снова наберите :!dir и просмотрите каталог.
+
+---> Заметьте, что если Вы выйдете из Vim и затем запустите его снова с
+     файлом TEST, этот файл будет точной копией учебника в тот момент, когда
+     Вы его сохранили.
+
+  5. Теперь удалите этот файл, набрав :!del TEST
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		       Урок 5.3: ВЫБОРОЧНОЕ СОХРАНЕНИЕ
+
+
+	 ** Для сохранения части файла, наберите :#,# w ИМЯ_ФАЙЛА **
+
+  1. Еще раз наберите :!dir или :!ls для получения списка файлов в текущем
+     каталоге и выберите подходящее имя, например TEST.
+
+  2. Переместите курсор к началу этой страницы и нажмите Ctrl-g для нахождения
+     номера строкиto. ЗАПОМНИТЕ ЭТОТ НОМЕР!
+
+  3. Теперь переместитесь в конец страницы и вновь наберите Ctrl-g. ЗАПОМНИТЕ
+     И ЭТОТ НОМЕР ТОЖЕ!
+
+  4. Для сохранения ТОЛЬКО ЧАСТИ файла наберите :#,# w TEST , где #,# --- это
+     номера, которые Вы запомнили (начало, конец), а TEST --- имя вашего файла.
+
+  5. Как и прежде, убедитесь в наличии этого файла командой :!dir , но НЕ
+     УДАЛЯЙТЕ его.
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		    Урок 5.4: ЧТЕНИЕ И ОБЪЕДИНЕНИЕ ФАЙЛОВ
+
+	  ** Для вставки содержимого файла, наберите  :r FILENAME **
+
+  1. Наберите :!dir для того, чтобы убедиться в том, что файл TEST все еще
+     существует.
+
+  2. Установите курсор в верхней части этой страницы.
+
+Замечание: После выполнения шага 3 Вы увидите Урок 5.3.	После этого
+	   перемещайтесь ВНИЗ, снова к этому уроку.
+
+  3. Теперь прочитайте Ваш файл TEST, используя команду :r TEST , где
+     TEST --- это имя файла.
+
+Замечание: Прочитанный Вами файл будет вставлен в том месте, где находится
+	   курсор.
+
+  4. Чтобы убедиться в том, что файл прочитан, переместитесь немного назад по
+     тексту и [A[Bзаметьте, что теперь существуют две копии Урока 5.3, исходная
+     и полученная из файла.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+				РЕЗЮМЕ УРОКА 5
+
+
+  1.  :!команда  исполняет внешнюю команду.
+
+      Некоторые полезные примеры:
+	  :!dir --- выводит список файлов в каталоге.
+	  :!del FILENAME --- удаляет файл FILENAME.
+
+  2.  :w FILENAME записывает текущий редактируемый файл на диск
+      под именем FILENAME.
+
+  3.  :#,#w FILENAME сохраняет строки от # до # в файл FILENAME.
+
+  4.  :r FILENAME считывает с диска файл FILENAME и помещает его в текущий
+      файл следом за позицией курсора.
+
+
+
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			  Урок 6.1: КОМАНДА СОЗДАНИЯ
+
+
+ ** Наберите o чтобы создать пустую строку под курсором и перейти в режим
+			   вставки (Insert mode) **
+
+  1. Переместите курсор вниз, к строке, помеченной --->.
+
+  2. Наберите o (в нижнем регистре) для того, чтобы создать пустую строку
+     НИЖЕ курсора и перейти в режим вставки (Insert mode).
+
+  3. Теперь скопируйте помеченную ---> строку и нажмите <ESC> для выхода из
+     режима вставки.
+
+---> После нажатия o курсор перейдет на новую пустую строку в режиме вставки.
+
+  4. Для создания строки ВЫШЕ курсора, просто наберите заглавную O, вместо
+     строчной o. Попробуйте проделать это с нижеследующей строкой.
+Создайте новую строку над этой, нажав Shift-O, поместив курсор на эту строку.
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			 Урок 6.2: КОМАНДА ДОБАВЛЕНИЯ
+
+	    ** Наберите a , чтобы вставить текст ПОСЛЕ курсора. **
+
+  1. Переместите курсор вниз, в конец первой строки, помеченной ---> ,
+     набрав $ в обычном режиме (Normal mode).
+
+  2. Наберите a (в нижнем регистре) для добавления текста ПОСЛЕ символа,
+     находящегося под курсором. (Заглавная A позволяет добавить в конец
+     строки.)
+
+Замечание: Это позволяет избежать нажатия i , последнего символа, текста для
+	   вставки, <ESC>, курсор-вправо, и, наконец, x , просто для того,
+	   чтобы добавить тест в конец строки!
+
+  3. Теперь завершите первую строку. Заметьте также, что добавление это в
+     точности то же самое, что и режим вставки, за исключением позиции, в
+     которую будет вставлен текст.
+
+---> Эта строчка позволит Вам попрактиковаться
+---> Эта строчка позволит Вам попрактиковаться в добавлении текста в конец
+     строки.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		       Урок 6.3: ЕЩЕ ОДИН СПОСОБ ЗАМЕНЫ
+
+
+       ** Наберите заглавную R для замены более, чем одного символа. **
+
+  1. Переместите курсор вниз, к строке, помеченной --->.
+
+  2. Расположите курсор в начале первого слова, отличающегося от
+     соответствующего в следующей строке, помеченной ---> (слово 'последней').
+
+  3. Теперь наберите R и замените остаток текста в первой строке, набрав
+     поверх старого текста так, чтобы обе строки стали одинаковыми.
+
+---> Первую строку можно сравнять с последней, используя клавиши.
+---> Первую строку можно сравнять с второй, используя R и набрав новый текст.
+
+  4. Обратите внимание, что при нажатии <ESC> для завершения, любой
+     не измененный текст сохранится.
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			Урок 6.4: УСТАНОВКА ПАРАМЕТРОВ
+
+
+** Установим параметры так, чтобы игнорировать регистр при поиске или замене **
+
+
+  1. Поищите слово 'игнорировать', набрав:
+     /игнорировать
+     Повторите поиск несколько раз, нажимая клавишу n
+
+  2. Включите параметр 'ic' (Игнорировать регистр), набрав:
+     :set ic
+
+  3. Теперь снова сделайте поиск слова 'игнорировать', нажав: n
+     Повторите поиск несколько раз, нажимая клавишу n
+
+  4. Включите параметры 'hlsearch' и 'incsearch':
+     :set hls is
+
+  5. Теперь опять введите команду поиска и посмотрите, что получится:
+     /игнорировать
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+				РЕЗЮМЕ УРОКА 6
+
+
+  1. Нажатие o создает строку НИЖЕ курсора и перемещает курсор в нее в режиме
+     вставки.
+     Нажатие заглавной O создает строку ВЫШЕ строки, в которой находится
+     курсор.
+
+  2. Наберите a для вставки текста ПОСЛЕ символа, на котором находится курсор.
+     Нажатие заглавной A автоматически перемещает Вас для добавления текста
+     в конец строки.
+
+  3. Нажатие заглавной R переводит Вас в режим замены до тех пор, пока не
+     будет нажата клавиша <ESC> для завершения.
+
+  4. Набрав ":set xxx" вы сможете включить параметр "xxx"
+
+
+
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		 Урок 7: КОМАНДЫ ПОЛУЧЕНИЯ ВСТРОЕННОЙ СПРАВКИ
+
+	       ** Используйте встроенную справочную систему **
+
+  Vim обладает мощной встроенной справочной системой. Для начала попробуйте
+  один из трех вариантов:
+	- нажмите клавишу <HELP> (если таковая имеется на клавиатуре)
+	- нажмите клавишу <F1> (если таковая имеется на клавиатуре)
+	- наберите   :help <ENTER>
+
+  Наберите   :q <ENTER>   чтобы закрыть окно справки.
+
+  Вы можете найти справку для любого понятия или команды, просто задав
+  соответствующий аргумент команде ":help". Попробуйте следующее (не забудьте
+  нажать <ENTER>):
+
+  :help w
+  :help c_<T
+  :help insert-index
+
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		     Урок 8: СОЗДАНИЕ СТАРТОВОГО СКРИПТА
+
+			** Включим возможности Vim **
+
+  Vim имеет намного больше возможностей, чем Vi, однако большинствао из них
+  выключены по умолчанию. Для того, чтобы начать использовать новые
+  возможности Вам следует создать файл "vimrc".
+
+  1. Отредактируйте файл "vimrc", его расположение зависит от используемой
+     системы:
+
+       :edit ~/.vimrc			для Unix
+       :edit $VIM/_vimrc		для MS-Windows
+
+  2. Теперь прочитайте пример файла "vimrc":
+
+       :read $VIMRUNTIME/vimrc_example.vim
+
+  3. Запишите файл:
+
+       :write
+
+  Теперь при следующем запуске Vim будет включена подсветка синтаксиса. Все
+  настройки, предпочитаемые Вами, могут быть добавлены в файл "vimrc".
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  На этом завершается Учебник Vim. Он был предназначен для того, чтобы дать
+  общее представление о редакторе Vim, достаточное для того, чтобы с легкостью
+  использовать его. Учебник далек от полноты, поскольку Vim имеет очень много
+  команд. Прочитайте теперь руководство пользователя: ":help user-manual".
+
+  Для дальнейшего чтения рекомендуется книга:
+	Vim - Vi Improved - Автор: Steve Oualline
+	Издатель: New Riders
+  Эта книга полностью посвящена Vim. Особенно полезна новичкам. Содержит
+  множество примеров и иллюстраций.
+  Взгляните на See http://iccf-holland.org/click5.html
+
+  Следующая книга более почтенного возраста и посвящена больше Vi, чем Vim,
+  однако также рекомендуется:
+	Learning the Vi Editor - Автор: Linda Lamb
+	Издатель: O'Reilly & Associates Inc.
+  Это хорошая книга для того, чтобы узнать все, что только можно проделывать с
+  Vi. Шестое издание также включает информацию о Vim.
+
+  Этот учебник был написан Michael C. Pierce и Robert K. Ware, Colorado School
+  of Mines с использованием идей, предложенных Charles Smith, Colorado State
+  University. E-mail: bware@mines.colorado.edu.
+
+  Доработано для Vim Bram Moolenaar.
+
+  Перевод: Андрей Киселев <a_kissel@eudoramail.com>, 2002.
+  Translator: Andrey Kiselev <a_kissel@eudoramail.com>, 2002.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff -Naur vim70.orig/runtime/tutor/tutor.vim vim70/runtime/tutor/tutor.vim
--- vim70.orig/runtime/tutor/tutor.vim	2006-03-18 12:20:36.000000000 -0800
+++ vim70/runtime/tutor/tutor.vim	2006-11-29 16:10:05.000000000 -0800
@@ -1,6 +1,6 @@
 " Vim tutor support file
 " Author: Eduardo F. Amatria <eferna1@platea.pntic.mec.es>
-" Last Change:	2006 Mar 18
+" Last Change:	2006 Sep 09
 
 " This small source file is used for detecting if a translation of the
 " tutor file exist, i.e., a tutor.xx file, where xx is the language.
@@ -93,9 +93,16 @@
   endif
 endif
 
-" The Greek tutor is available in two encodings, guess which one to use
-if s:ext =~? '\.gr' && &enc =~ 737
-  let s:ext = ".gr.cp737"
+" The Greek tutor is available in three encodings, guess what to use.
+" We used ".gr" (Greece) instead of ".el" (Greek); accept both.
+if s:ext =~? '\.gr\|\.el'
+  if &enc == "iso-8859-7"
+    let s:ext = ".gr"
+  elseif &enc == "utf-8"
+    let s:ext = ".gr.utf-8"
+  elseif &enc =~ 737
+    let s:ext = ".gr.cp737"
+  endif
 endif
 
 " The Slovak tutor is available in two encodings, guess which one to use
@@ -103,11 +110,15 @@
   let s:ext = ".sk.cp1250"
 endif
 
-" The Russian tutor is available in two encodings, guess which one to use.
-" This segment is from the above lines and modified by
-" Alexey I. Froloff <raorn@altlinux.org> for Russian vim tutorial
-if s:ext =~? '\.ru' && &enc =~ 1251
-  let s:ext = ".ru.cp1251"
+" The Russian tutor is available in three encodings, guess which one to use.
+if s:ext =~? '\.ru'
+  if &enc == 'utf-8'
+    let s:ext = '.ru.utf-8'
+  elseif &enc =~ '1251'
+    let s:ext = '.ru.cp1251'
+  elseif &enc =~ 'koi8'
+    let s:ext = '.ru'
+  endif
 endif
 
 " Somehow ".ge" (Germany) is sometimes used for ".de" (Deutsch).
diff -Naur vim70.orig/src/auto/configure vim70/src/auto/configure
--- vim70.orig/src/auto/configure	2006-05-04 03:46:19.000000000 -0700
+++ vim70/src/auto/configure	2006-11-29 16:10:11.000000000 -0800
@@ -4014,7 +4014,7 @@
       LDFLAGS=$ldflags_save
       if test $perl_ok = yes; then
 	if test "X$perlcppflags" != "X"; then
-	  PERL_CFLAGS="$perlcppflags"
+	  	  PERL_CFLAGS=`echo "$perlcppflags" | sed 's/-pipe //'`
 	fi
 	if test "X$perlldflags" != "X"; then
 	  LDFLAGS="$perlldflags $LDFLAGS"
@@ -4256,7 +4256,7 @@
 echo $ECHO_N "checking if -pthread should be used... $ECHO_C" >&6
 	threadsafe_flag=
 	thread_lib=
-	if test "x$MACOSX" != "xyes"; then
+	        if test "`(uname) 2>/dev/null`" != Darwin; then
 	  test "$GCC" = yes && threadsafe_flag="-pthread"
 	  if test "`(uname) 2>/dev/null`" = FreeBSD; then
 	    threadsafe_flag="-D_THREAD_SAFE"
@@ -11555,8 +11555,8 @@
 else
   echo "$as_me:$LINENO: result: empty: automatic terminal library selection" >&5
 echo "${ECHO_T}empty: automatic terminal library selection" >&6
-            case "`uname -s 2>/dev/null`" in
-	OSF1)	tlibs="ncurses curses termlib termcap";;
+              case "`uname -s 2>/dev/null`" in
+	OSF1|SCO_SV)	tlibs="ncurses curses termlib termcap";;
 	*)	tlibs="ncurses termlib termcap curses";;
   esac
   for libname in $tlibs; do
@@ -15302,7 +15302,7 @@
 	&& test "x$GUITYPE" != "xCARBONGUI"; then
   echo "$as_me:$LINENO: checking whether we need -framework Carbon" >&5
 echo $ECHO_N "checking whether we need -framework Carbon... $ECHO_C" >&6
-    if test "x$enable_multibyte" = "xyes" || test "x$features" == "xbig" \
+    if test "x$enable_multibyte" = "xyes" || test "x$features" = "xbig" \
 	|| test "x$features" = "xhuge"; then
     LIBS="$LIBS -framework Carbon"
     echo "$as_me:$LINENO: result: yes" >&5
diff -Naur vim70.orig/src/buffer.c vim70/src/buffer.c
--- vim70.orig/src/buffer.c	2006-04-26 14:37:23.000000000 -0700
+++ vim70/src/buffer.c	2006-11-29 16:10:15.000000000 -0800
@@ -434,12 +434,8 @@
     if (usingNetbeans)
 	netbeans_file_closed(buf);
 #endif
-#ifdef FEAT_AUTOCHDIR
-    /* Change directories when the acd option is set on. */
-    if (p_acd && curbuf->b_ffname != NULL
-				     && vim_chdirfile(curbuf->b_ffname) == OK)
-	shorten_fnames(TRUE);
-#endif
+    /* Change directories when the 'acd' option is set. */
+    DO_AUTOCHDIR
 
     /*
      * Remove the buffer from the list.
@@ -1212,11 +1208,11 @@
     {
 # ifdef FEAT_WINDOWS
 	/* jump to first window containing buf if one exists ("useopen") */
-	if (vim_strchr(p_swb, 'o') && buf_jump_open_win(buf))
+	if (vim_strchr(p_swb, 'o') != NULL && buf_jump_open_win(buf))
 	    return OK;
 	/* jump to first window in any tab page containing buf if one exists
 	 * ("usetab") */
-	if (vim_strchr(p_swb, 'a') && buf_jump_open_tab(buf))
+	if (vim_strchr(p_swb, 'a') != NULL && buf_jump_open_tab(buf))
 	    return OK;
 	if (win_split(0, 0) == FAIL)
 # endif
@@ -1390,7 +1386,8 @@
     }
     else
     {
-	need_fileinfo = TRUE;		/* display file info after redraw */
+	if (!msg_silent)
+	    need_fileinfo = TRUE;	/* display file info after redraw */
 	(void)buf_check_timestamp(curbuf, FALSE); /* check if file changed */
 #ifdef FEAT_AUTOCMD
 	curwin->w_topline = 1;
@@ -1422,12 +1419,8 @@
 	netbeans_file_activated(curbuf);
 #endif
 
-#ifdef FEAT_AUTOCHDIR
-    /* Change directories when the acd option is set on. */
-    if (p_acd && curbuf->b_ffname != NULL
-				     && vim_chdirfile(curbuf->b_ffname) == OK)
-	shorten_fnames(TRUE);
-#endif
+    /* Change directories when the 'acd' option is set. */
+    DO_AUTOCHDIR
 
 #ifdef FEAT_KEYMAP
     if (curbuf->b_kmap_state & KEYMAP_INIT)
@@ -1436,6 +1429,18 @@
     redraw_later(NOT_VALID);
 }
 
+#if defined(FEAT_AUTOCHDIR) || defined(PROTO)
+/*
+ * Change to the directory of the current buffer.
+ */
+    void
+do_autochdir()
+{
+    if (curbuf->b_ffname != NULL && vim_chdirfile(curbuf->b_ffname) == OK)
+	shorten_fnames(TRUE);
+}
+#endif
+
 /*
  * functions for dealing with the buffer list
  */
@@ -1837,13 +1842,13 @@
     if (options & GETF_SWITCH)
     {
 	/* use existing open window for buffer if wanted */
-	if (vim_strchr(p_swb, 'o'))     /* useopen */
+	if (vim_strchr(p_swb, 'o') != NULL)	/* useopen */
 	    wp = buf_jump_open_win(buf);
 	/* use existing open window in any tab page for buffer if wanted */
-	if (vim_strchr(p_swb, 'a'))     /* usetab */
+	if (vim_strchr(p_swb, 'a') != NULL)	/* usetab */
 	    wp = buf_jump_open_tab(buf);
 	/* split window if wanted ("split") */
-	if (wp == NULL && vim_strchr(p_swb, 't') && !bufempty())
+	if (wp == NULL && vim_strchr(p_swb, 'l') != NULL && !bufempty())
 	{
 	    if (win_split(0, 0) == FAIL)
 		return FAIL;
@@ -3324,7 +3329,7 @@
     {
 	usefmt = eval_to_string_safe(fmt + 2, NULL, use_sandbox);
 	if (usefmt == NULL)
-	    usefmt = (char_u *)"";
+	    usefmt = fmt;
     }
 #endif
 
@@ -4215,7 +4220,7 @@
 
     /* Use the name from the associated buffer if it exists. */
     bp = buflist_findnr(aep->ae_fnum);
-    if (bp == NULL)
+    if (bp == NULL || bp->b_fname == NULL)
 	return aep->ae_fname;
     return bp->b_fname;
 }
@@ -5420,11 +5425,7 @@
     buf_T	*newbuf;
     int		differ = TRUE;
     linenr_T	lnum;
-#ifdef FEAT_AUTOCMD
     aco_save_T	aco;
-#else
-    buf_T	*old_curbuf = curbuf;
-#endif
     exarg_T	ea;
 
     /* Allocate a buffer without putting it in the buffer list. */
@@ -5439,13 +5440,8 @@
 	return TRUE;
     }
 
-#ifdef FEAT_AUTOCMD
     /* set curwin/curbuf to buf and save a few things */
     aucmd_prepbuf(&aco, newbuf);
-#else
-    curbuf = newbuf;
-    curwin->w_buffer = newbuf;
-#endif
 
     if (ml_open(curbuf) == OK
 	    && readfile(buf->b_ffname, buf->b_fname,
@@ -5466,13 +5462,8 @@
     }
     vim_free(ea.cmd);
 
-#ifdef FEAT_AUTOCMD
     /* restore curwin/curbuf and a few other things */
     aucmd_restbuf(&aco);
-#else
-    curbuf = old_curbuf;
-    curwin->w_buffer = old_curbuf;
-#endif
 
     if (curbuf != newbuf)	/* safety check */
 	wipe_buffer(newbuf, FALSE);
diff -Naur vim70.orig/src/configure vim70/src/configure
--- vim70.orig/src/configure	2006-05-07 07:17:49.000000000 -0700
+++ vim70/src/configure	2006-11-29 16:09:55.000000000 -0800
@@ -2,5 +2,9 @@
 # run the automatically generated configure script
 CONFIG_STATUS=auto/config.status \
 	auto/configure "$@" --srcdir="${srcdir:-.}" --cache-file=auto/config.cache
+result=$?
+
 # Stupid autoconf 2.5x causes this file to be left behind.
 if test -f configure.lineno; then rm -f configure.lineno; fi
+
+exit $result
diff -Naur vim70.orig/src/configure.in vim70/src/configure.in
--- vim70.orig/src/configure.in	2006-05-04 03:46:11.000000000 -0700
+++ vim70/src/configure.in	2006-11-29 16:10:11.000000000 -0800
@@ -508,7 +508,8 @@
       LDFLAGS=$ldflags_save
       if test $perl_ok = yes; then
 	if test "X$perlcppflags" != "X"; then
-	  PERL_CFLAGS="$perlcppflags"
+	  dnl remove -pipe, it confuses cproto
+	  PERL_CFLAGS=`echo "$perlcppflags" | sed 's/-pipe //'`
 	fi
 	if test "X$perlldflags" != "X"; then
 	  LDFLAGS="$perlldflags $LDFLAGS"
@@ -680,7 +681,8 @@
 	AC_MSG_CHECKING([if -pthread should be used])
 	threadsafe_flag=
 	thread_lib=
-	if test "x$MACOSX" != "xyes"; then
+	dnl if test "x$MACOSX" != "xyes"; then
+        if test "`(uname) 2>/dev/null`" != Darwin; then
 	  test "$GCC" = yes && threadsafe_flag="-pthread"
 	  if test "`(uname) 2>/dev/null`" = FreeBSD; then
 	    threadsafe_flag="-D_THREAD_SAFE"
@@ -2150,8 +2152,9 @@
   dnl  Newer versions of ncurses are preferred over anything.
   dnl  Older versions of ncurses have bugs, get a new one!
   dnl  Digital Unix (OSF1) should use curses (Ronald Schild).
+  dnl  On SCO Openserver should prefer termlib (Roger Cornelius).
   case "`uname -s 2>/dev/null`" in
-	OSF1)	tlibs="ncurses curses termlib termcap";;
+	OSF1|SCO_SV)	tlibs="ncurses curses termlib termcap";;
 	*)	tlibs="ncurses termlib termcap curses";;
   esac
   for libname in $tlibs; do
@@ -2835,7 +2838,7 @@
 	&& test "x$GUITYPE" != "xCARBONGUI"; then
   AC_MSG_CHECKING(whether we need -framework Carbon)
   dnl check for MACOSX without Carbon GUI, but with FEAT_MBYTE
-  if test "x$enable_multibyte" = "xyes" || test "x$features" == "xbig" \
+  if test "x$enable_multibyte" = "xyes" || test "x$features" = "xbig" \
 	|| test "x$features" = "xhuge"; then
     LIBS="$LIBS -framework Carbon"
     AC_MSG_RESULT(yes)
diff -Naur vim70.orig/src/edit.c vim70/src/edit.c
--- vim70.orig/src/edit.c	2006-05-07 04:48:51.000000000 -0700
+++ vim70/src/edit.c	2006-11-29 16:10:14.000000000 -0800
@@ -129,7 +129,7 @@
 
 static void ins_ctrl_x __ARGS((void));
 static int  has_compl_option __ARGS((int dict_opt));
-static int ins_compl_add __ARGS((char_u *str, int len, int icase, char_u *fname, char_u **cptext, int cdir, int flags, int dup));
+static int ins_compl_add __ARGS((char_u *str, int len, int icase, char_u *fname, char_u **cptext, int cdir, int flags, int adup));
 static int  ins_compl_equal __ARGS((compl_T *match, char_u *str, int len));
 static void ins_compl_longest_match __ARGS((compl_T *match));
 static void ins_compl_add_matches __ARGS((int num_matches, char_u **matches, int icase));
@@ -707,6 +707,11 @@
 	lastc = c;			/* remember previous char for CTRL-D */
 	c = safe_vgetc();
 
+#ifdef FEAT_AUTOCMD
+	/* Don't want K_CURSORHOLD for the second key, e.g., after CTRL-V. */
+	did_cursorhold = TRUE;
+#endif
+
 #ifdef FEAT_RIGHTLEFT
 	if (p_hkmap && KeyTyped)
 	    c = hkmap(c);		/* Hebrew mode mapping */
@@ -719,9 +724,14 @@
 #ifdef FEAT_INS_EXPAND
 	/*
 	 * Special handling of keys while the popup menu is visible or wanted
-	 * and the cursor is still in the completed word.
+	 * and the cursor is still in the completed word.  Only when there is
+	 * a match, skip this when no matches were found.
 	 */
-	if (compl_started && pum_wanted() && curwin->w_cursor.col >= compl_col)
+	if (compl_started
+		&& pum_wanted()
+		&& curwin->w_cursor.col >= compl_col
+		&& (compl_shown_match == NULL
+		    || compl_shown_match != compl_shown_match->cp_next))
 	{
 	    /* BS: Delete one character from "compl_leader". */
 	    if ((c == K_BS || c == Ctrl_H)
@@ -751,7 +761,7 @@
 		    continue;
 		}
 
-		/* Pressing CTRL-Y selects the current match.  Shen
+		/* Pressing CTRL-Y selects the current match.  When
 		 * compl_enter_selects is set the Enter key does the same. */
 		if (c == Ctrl_Y || (compl_enter_selects
 				   && (c == CAR || c == K_KENTER || c == NL)))
@@ -877,6 +887,7 @@
 		/* Close the cmdline window. */
 		cmdwin_result = K_IGNORE;
 		got_int = FALSE; /* don't stop executing autocommands et al. */
+		nomove = TRUE;
 		goto doESCkey;
 	    }
 #endif
@@ -912,6 +923,7 @@
 		if (cmdchar != 'r' && cmdchar != 'v')
 		    apply_autocmds(EVENT_INSERTLEAVE, NULL, NULL,
 							       FALSE, curbuf);
+		did_cursorhold = FALSE;
 #endif
 		return (c == Ctrl_O);
 	    }
@@ -1383,6 +1395,12 @@
 	    break;
 	}   /* end of switch (c) */
 
+#ifdef FEAT_AUTOCMD
+	/* If typed something may trigger CursorHoldI again. */
+	if (c != K_CURSORHOLD)
+	    did_cursorhold = FALSE;
+#endif
+
 	/* If the cursor was moved we didn't just insert a space */
 	if (arrow_used)
 	    inserted_space = FALSE;
@@ -2112,7 +2130,7 @@
  * maybe because alloc() returns NULL, then FAIL is returned.
  */
     static int
-ins_compl_add(str, len, icase, fname, cptext, cdir, flags, dup)
+ins_compl_add(str, len, icase, fname, cptext, cdir, flags, adup)
     char_u	*str;
     int		len;
     int		icase;
@@ -2120,7 +2138,7 @@
     char_u	**cptext;   /* extra text for popup menu or NULL */
     int		cdir;
     int		flags;
-    int		dup;	    /* accept duplicate match */
+    int		adup;	    /* accept duplicate match */
 {
     compl_T	*match;
     int		dir = (cdir == 0 ? compl_direction : cdir);
@@ -2134,13 +2152,13 @@
     /*
      * If the same match is already present, don't add it.
      */
-    if (compl_first_match != NULL && !dup)
+    if (compl_first_match != NULL && !adup)
     {
 	match = compl_first_match;
 	do
 	{
 	    if (    !(match->cp_flags & ORIGINAL_TEXT)
-		    && ins_compl_equal(match, str, len)
+		    && STRNCMP(match->cp_str, str, len) == 0
 		    && match->cp_str[len] == NUL)
 		return NOTDONE;
 	    match = match->cp_next;
@@ -2399,7 +2417,7 @@
     /* compl_pattern doesn't need to be set */
     compl_orig_text = vim_strnsave(ml_get_curline() + compl_col, compl_length);
     if (compl_orig_text == NULL || ins_compl_add(compl_orig_text,
-			-1, FALSE, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK)
+			-1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK)
 	return;
 
     /* Handle like dictionary completion. */
@@ -2409,6 +2427,7 @@
     compl_matches = ins_compl_make_cyclic();
     compl_started = TRUE;
     compl_used_match = TRUE;
+    compl_cont_status = 0;
 
     compl_curr_match = compl_first_match;
     ins_complete(Ctrl_N);
@@ -2753,6 +2772,7 @@
 	}
 	else
 # endif
+	    if (count > 0)	/* avoid warning for using "files" uninit */
 	{
 	    ins_compl_files(count, files, thesaurus, flags,
 							&regmatch, buf, &dir);
@@ -2813,7 +2833,7 @@
 			ptr = find_word_end(ptr);
 		    add_r = ins_compl_add_infercase(regmatch->startp[0],
 					  (int)(ptr - regmatch->startp[0]),
-						     FALSE, files[i], *dir, 0);
+						     p_ic, files[i], *dir, 0);
 		    if (thesaurus)
 		    {
 			char_u *wstart;
@@ -2849,7 +2869,7 @@
 				ptr = find_word_end(ptr);
 			    add_r = ins_compl_add_infercase(wstart,
 				    (int)(ptr - wstart),
-				    FALSE, files[i], *dir, 0);
+				    p_ic, files[i], *dir, 0);
 			}
 		    }
 		    if (add_r == OK)
@@ -3015,9 +3035,6 @@
     if ((int)(p - line) - (int)compl_col <= 0)
 	return K_BS;
 
-    /* For redo we need to repeat this backspace. */
-    AppendCharToRedobuff(K_BS);
-
     /* Deleted more than what was used to find matches or didn't finish
      * finding all matches: need to look for matches all over again. */
     if (curwin->w_cursor.col <= compl_col + compl_length
@@ -3046,7 +3063,6 @@
     ins_compl_delete();
     ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
     compl_used_match = FALSE;
-    compl_enter_selects = FALSE;
 
     if (compl_started)
 	ins_compl_set_original_text(compl_leader);
@@ -3076,6 +3092,7 @@
 	compl_restarting = FALSE;
     }
 
+#if 0   /* disabled, made CTRL-L, BS and typing char jump to original text. */
     if (!compl_used_match)
     {
 	/* Go to the original text, since none of the matches is inserted. */
@@ -3087,9 +3104,15 @@
 	compl_curr_match = compl_shown_match;
 	compl_shows_dir = compl_direction;
     }
+#endif
+    compl_enter_selects = !compl_used_match;
 
     /* Show the popup menu with a different set of matches. */
     ins_compl_show_pum();
+
+    /* Don't let Enter select the original text when there is no popup menu. */
+    if (compl_match_array == NULL)
+	compl_enter_selects = FALSE;
 }
 
 /*
@@ -3115,10 +3138,6 @@
 #endif
 	ins_char(c);
 
-    /* For redo we need to count this character so that the number of
-     * backspaces is correct. */
-    AppendCharToRedobuff(c);
-
     /* If we didn't complete finding matches we must search again. */
     if (compl_was_interrupted)
 	ins_compl_restart();
@@ -3175,10 +3194,33 @@
     char_u	*p;
     int		len = curwin->w_cursor.col - compl_col;
     int		c;
+    compl_T	*cp;
 
     p = compl_shown_match->cp_str;
     if ((int)STRLEN(p) <= len)   /* the match is too short */
-	return;
+    {
+	/* When still at the original match use the first entry that matches
+	 * the leader. */
+	if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
+	{
+	    p = NULL;
+	    for (cp = compl_shown_match->cp_next; cp != NULL
+				 && cp != compl_first_match; cp = cp->cp_next)
+	    {
+		if (compl_leader == NULL
+			|| ins_compl_equal(cp, compl_leader,
+						   (int)STRLEN(compl_leader)))
+		{
+		    p = cp->cp_str;
+		    break;
+		}
+	    }
+	    if (p == NULL || (int)STRLEN(p) <= len)
+		return;
+	}
+	else
+	    return;
+    }
     p += len;
 #ifdef FEAT_MBYTE
     c = mb_ptr2char(p);
@@ -3198,7 +3240,6 @@
     int	    c;
 {
     char_u	*ptr;
-    int		temp;
     int		want_cindent;
     int		retval = FALSE;
 
@@ -3354,6 +3395,7 @@
 	    if (compl_curr_match != NULL || compl_leader != NULL || c == Ctrl_E)
 	    {
 		char_u	*p;
+		int	temp = 0;
 
 		/*
 		 * If any of the original typed text has been changed, eg when
@@ -3369,16 +3411,21 @@
 		    ptr = compl_leader;
 		else
 		    ptr = compl_orig_text;
-		p = compl_orig_text;
-		for (temp = 0; p[temp] != NUL && p[temp] == ptr[temp]; ++temp)
-		    ;
+		if (compl_orig_text != NULL)
+		{
+		    p = compl_orig_text;
+		    for (temp = 0; p[temp] != NUL && p[temp] == ptr[temp];
+								       ++temp)
+			;
 #ifdef FEAT_MBYTE
-		if (temp > 0)
-		    temp -= (*mb_head_off)(compl_orig_text, p + temp);
+		    if (temp > 0)
+			temp -= (*mb_head_off)(compl_orig_text, p + temp);
 #endif
-		for (p += temp; *p != NUL; mb_ptr_adv(p))
-		    AppendCharToRedobuff(K_BS);
-		AppendToRedobuffLit(ptr + temp, -1);
+		    for (p += temp; *p != NUL; mb_ptr_adv(p))
+			AppendCharToRedobuff(K_BS);
+		}
+		if (ptr != NULL)
+		    AppendToRedobuffLit(ptr + temp, -1);
 	    }
 
 #ifdef FEAT_CINDENT
@@ -3578,7 +3625,7 @@
 {
     char_u	*word;
     int		icase = FALSE;
-    int		dup = FALSE;
+    int		adup = FALSE;
     char_u	*(cptext[CPT_COUNT]);
 
     if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL)
@@ -3595,7 +3642,7 @@
 	if (get_dict_string(tv->vval.v_dict, (char_u *)"icase", FALSE) != NULL)
 	    icase = get_dict_number(tv->vval.v_dict, (char_u *)"icase");
 	if (get_dict_string(tv->vval.v_dict, (char_u *)"dup", FALSE) != NULL)
-	    dup = get_dict_number(tv->vval.v_dict, (char_u *)"dup");
+	    adup = get_dict_number(tv->vval.v_dict, (char_u *)"dup");
     }
     else
     {
@@ -3604,7 +3651,7 @@
     }
     if (word == NULL || *word == NUL)
 	return FAIL;
-    return ins_compl_add(word, -1, icase, NULL, cptext, dir, 0, dup);
+    return ins_compl_add(word, -1, icase, NULL, cptext, dir, 0, adup);
 }
 #endif
 
@@ -3796,7 +3843,7 @@
 		    TAG_INS_COMP | (ctrl_x_mode ? TAG_VERBOSE : 0),
 		    TAG_MANY, curbuf->b_ffname) == OK && num_matches > 0)
 	    {
-		ins_compl_add_matches(num_matches, matches, FALSE);
+		ins_compl_add_matches(num_matches, matches, p_ic);
 	    }
 	    p_ic = save_p_ic;
 	    break;
@@ -3837,7 +3884,7 @@
 	    num_matches = expand_spelling(first_match_pos.lnum,
 				 first_match_pos.col, compl_pattern, &matches);
 	    if (num_matches > 0)
-		ins_compl_add_matches(num_matches, matches, FALSE);
+		ins_compl_add_matches(num_matches, matches, p_ic);
 #endif
 	    break;
 
@@ -3862,6 +3909,8 @@
 	    {
 		int	flags = 0;
 
+		++msg_silent;  /* Don't want messages for wrapscan. */
+
 		/* ctrl_x_mode == CTRL_X_WHOLE_LINE || word-wise search that
 		 * has added a word that was at the beginning of the line */
 		if (	ctrl_x_mode == CTRL_X_WHOLE_LINE
@@ -3873,6 +3922,7 @@
 							      compl_direction,
 				 compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG,
 							RE_LAST, (linenr_T)0);
+		--msg_silent;
 		if (!compl_started)
 		{
 		    /* set "compl_started" even on fail */
@@ -3971,7 +4021,7 @@
 			    continue;
 		    }
 		}
-		if (ins_compl_add_infercase(ptr, len, FALSE,
+		if (ins_compl_add_infercase(ptr, len, p_ic,
 				 ins_buf == curbuf ? NULL : ins_buf->b_sfname,
 					   0, flags) != NOTDONE)
 		{
@@ -3996,7 +4046,7 @@
 	    if (got_int)
 		break;
 	    /* Fill the popup menu as soon as possible. */
-	    if (pum_wanted() && type != -1)
+	    if (type != -1)
 		ins_compl_check_keys(0);
 
 	    if ((ctrl_x_mode != 0 && ctrl_x_mode != CTRL_X_WHOLE_LINE)
@@ -4100,6 +4150,21 @@
 		&& compl_shown_match->cp_next != NULL
 		&& compl_shown_match->cp_next != compl_first_match)
 	    compl_shown_match = compl_shown_match->cp_next;
+
+	/* If we didn't find it searching forward, and compl_shows_dir is
+	 * backward, find the last match. */
+	if (compl_shows_dir == BACKWARD
+		&& !ins_compl_equal(compl_shown_match,
+				      compl_leader, (int)STRLEN(compl_leader))
+		&& (compl_shown_match->cp_next == NULL
+		    || compl_shown_match->cp_next == compl_first_match))
+	{
+	    while (!ins_compl_equal(compl_shown_match,
+				      compl_leader, (int)STRLEN(compl_leader))
+		    && compl_shown_match->cp_prev != NULL
+		    && compl_shown_match->cp_prev != compl_first_match)
+		compl_shown_match = compl_shown_match->cp_prev;
+	}
     }
 
     if (allow_get_expansion && insert_match
@@ -4124,8 +4189,6 @@
     {
 	if (compl_shows_dir == FORWARD && compl_shown_match->cp_next != NULL)
 	{
-	    if (compl_pending != 0)
-		--compl_pending;
 	    compl_shown_match = compl_shown_match->cp_next;
 	    found_end = (compl_first_match != NULL
 			   && (compl_shown_match->cp_next == compl_first_match
@@ -4134,14 +4197,24 @@
 	else if (compl_shows_dir == BACKWARD
 					&& compl_shown_match->cp_prev != NULL)
 	{
-	    if (compl_pending != 0)
-		++compl_pending;
 	    found_end = (compl_shown_match == compl_first_match);
 	    compl_shown_match = compl_shown_match->cp_prev;
 	    found_end |= (compl_shown_match == compl_first_match);
 	}
 	else
 	{
+	    if (!allow_get_expansion)
+	    {
+		if (advance)
+		{
+		    if (compl_shows_dir == BACKWARD)
+			compl_pending -= todo + 1;
+		    else
+			compl_pending += todo + 1;
+		}
+		return -1;
+	    }
+
 	    if (advance)
 	    {
 		if (compl_shows_dir == BACKWARD)
@@ -4149,14 +4222,27 @@
 		else
 		    ++compl_pending;
 	    }
-	    if (!allow_get_expansion)
-		return -1;
 
 	    /* Find matches. */
 	    num_matches = ins_compl_get_exp(&compl_startpos);
-	    if (compl_pending != 0 && compl_direction == compl_shows_dir
+
+	    /* handle any pending completions */
+	    while (compl_pending != 0 && compl_direction == compl_shows_dir
 								   && advance)
-		compl_shown_match = compl_curr_match;
+	    {
+		if (compl_pending > 0 && compl_shown_match->cp_next != NULL)
+		{
+		    compl_shown_match = compl_shown_match->cp_next;
+		    --compl_pending;
+		}
+		if (compl_pending < 0 && compl_shown_match->cp_prev != NULL)
+		{
+		    compl_shown_match = compl_shown_match->cp_prev;
+		    ++compl_pending;
+		}
+		else
+		    break;
+	    }
 	    found_end = FALSE;
 	}
 	if ((compl_shown_match->cp_flags & ORIGINAL_TEXT) == 0
@@ -4265,9 +4351,9 @@
 	return;
     count = 0;
 
-    ++no_mapping;
+    /* Check for a typed key.  Do use mappings, otherwise vim_is_ctrl_x_key()
+     * can't do its work correctly. */
     c = vpeekc_any();
-    --no_mapping;
     if (c != NUL)
     {
 	if (vim_is_ctrl_x_key(c) && c != Ctrl_X && c != Ctrl_R)
@@ -4277,12 +4363,27 @@
 	    (void)ins_compl_next(FALSE, ins_compl_key2count(c),
 						    c != K_UP && c != K_DOWN);
 	}
-	else if (c != Ctrl_R)
-	    compl_interrupted = TRUE;
+	else
+	{
+	    /* Need to get the character to have KeyTyped set.  We'll put it
+	     * back with vungetc() below. */
+	    c = safe_vgetc();
+
+	    /* Don't interrupt completion when the character wasn't typed,
+	     * e.g., when doing @q to replay keys. */
+	    if (c != Ctrl_R && KeyTyped)
+		compl_interrupted = TRUE;
+
+	    vungetc(c);
+	}
     }
     if (compl_pending != 0 && !got_int)
-	(void)ins_compl_next(FALSE, compl_pending > 0
-				      ? compl_pending : -compl_pending, TRUE);
+    {
+	int todo = compl_pending > 0 ? compl_pending : -compl_pending;
+
+	compl_pending = 0;
+	(void)ins_compl_next(FALSE, todo, TRUE);
+    }
 }
 
 /*
@@ -4611,10 +4712,12 @@
 				     (int)STRLEN(compl_pattern), curs_col);
 	    if (compl_xp.xp_context == EXPAND_UNSUCCESSFUL
 		    || compl_xp.xp_context == EXPAND_NOTHING)
-		return FAIL;
-	    startcol = (int)(compl_xp.xp_pattern - compl_pattern);
-	    compl_col = startcol;
-	    compl_length = curs_col - startcol;
+		/* No completion possible, use an empty pattern to get a
+		 * "pattern not found" message. */
+		compl_col = curs_col;
+	    else
+		compl_col = (int)(compl_xp.xp_pattern - compl_pattern);
+	    compl_length = curs_col - compl_col;
 	}
 	else if (ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI)
 	{
@@ -4668,11 +4771,17 @@
 	    else
 		compl_col = spell_word_start(startcol);
 	    if (compl_col >= (colnr_T)startcol)
-		return FAIL;
-	    spell_expand_check_cap(compl_col);
+	    {
+		compl_length = 0;
+		compl_col = curs_col;
+	    }
+	    else
+	    {
+		spell_expand_check_cap(compl_col);
+		compl_length = (int)curs_col - compl_col;
+	    }
 	    /* Need to obtain "line" again, it may have become invalid. */
 	    line = ml_get(curwin->w_cursor.lnum);
-	    compl_length = (int)curs_col - compl_col;
 	    compl_pattern = vim_strnsave(line + compl_col, compl_length);
 	    if (compl_pattern == NULL)
 #endif
@@ -4720,7 +4829,7 @@
 	vim_free(compl_orig_text);
 	compl_orig_text = vim_strnsave(line + compl_col, compl_length);
 	if (compl_orig_text == NULL || ins_compl_add(compl_orig_text,
-			-1, FALSE, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK)
+			-1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK)
 	{
 	    vim_free(compl_pattern);
 	    compl_pattern = NULL;
@@ -5227,8 +5336,16 @@
 	/* Format with 'formatexpr' when it's set.  Use internal formatting
 	 * when 'formatexpr' isn't set or it returns non-zero. */
 #if defined(FEAT_EVAL)
-	if (*curbuf->b_p_fex == NUL
-			     || fex_format(curwin->w_cursor.lnum, 1L, c) != 0)
+	int do_internal = TRUE;
+
+	if (*curbuf->b_p_fex != NUL)
+	{
+	    do_internal = (fex_format(curwin->w_cursor.lnum, 1L, c) != 0);
+	    /* It may be required to save for undo again, e.g. when setline()
+	     * was called. */
+	    ins_need_undo = TRUE;
+	}
+	if (do_internal)
 #endif
 	    internal_format(textwidth, second_indent, flags, c == NUL);
     }
@@ -8508,7 +8625,12 @@
     tpos = curwin->w_cursor;
     if (oneleft() == OK)
     {
-	start_arrow(&tpos);
+#if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+	/* Only call start_arrow() when not busy with preediting, it will
+	 * break undo.  K_LEFT is inserted in im_correct_cursor(). */
+	if (!im_is_preediting())
+#endif
+	    start_arrow(&tpos);
 #ifdef FEAT_RIGHTLEFT
 	/* If exit reversed string, position is fixed */
 	if (revins_scol != -1 && (int)curwin->w_cursor.col >= revins_scol)
@@ -8700,7 +8822,11 @@
     if (mod_mask & MOD_MASK_CTRL)
     {
 	/* <C-PageUp>: tab page back */
-	goto_tabpage(-1);
+	if (first_tabpage->tp_next != NULL)
+	{
+	    start_arrow(&curwin->w_cursor);
+	    goto_tabpage(-1);
+	}
 	return;
     }
 #endif
@@ -8759,7 +8885,11 @@
     if (mod_mask & MOD_MASK_CTRL)
     {
 	/* <C-PageDown>: tab page forward */
-	goto_tabpage(0);
+	if (first_tabpage->tp_next != NULL)
+	{
+	    start_arrow(&curwin->w_cursor);
+	    goto_tabpage(0);
+	}
 	return;
     }
 #endif
@@ -9074,6 +9204,10 @@
 #ifdef FEAT_CINDENT
     can_cindent = TRUE;
 #endif
+#ifdef FEAT_FOLDING
+    /* When inserting a line the cursor line must never be in a closed fold. */
+    foldOpenCursor();
+#endif
 
     return (!i);
 }
diff -Naur vim70.orig/src/eval.c vim70/src/eval.c
--- vim70.orig/src/eval.c	2006-05-05 10:15:26.000000000 -0700
+++ vim70/src/eval.c	2006-11-29 16:10:23.000000000 -0800
@@ -166,7 +166,6 @@
     int		uf_tm_count;	/* nr of calls */
     proftime_T	uf_tm_total;	/* time spend in function + children */
     proftime_T	uf_tm_self;	/* time spend in function itself */
-    proftime_T	uf_tm_start;	/* time at function call */
     proftime_T	uf_tm_children;	/* time spent in children this call */
     /* profiling the function per line */
     int		*uf_tml_count;	/* nr of times line was executed */
@@ -191,8 +190,6 @@
 #define FC_RANGE    2		/* function accepts range */
 #define FC_DICT	    4		/* Dict function, uses "self" */
 
-#define DEL_REFCOUNT	999999	/* list/dict is being deleted */
-
 /*
  * All user-defined functions are found in this hashtable.
  */
@@ -345,6 +342,9 @@
     {VV_NAME("swapchoice",	 VAR_STRING), 0},
     {VV_NAME("swapcommand",	 VAR_STRING), VV_RO},
     {VV_NAME("char",		 VAR_STRING), VV_RO},
+    {VV_NAME("mouse_win",	 VAR_NUMBER), 0},
+    {VV_NAME("mouse_lnum",	 VAR_NUMBER), 0},
+    {VV_NAME("mouse_col",	 VAR_NUMBER), 0},
 };
 
 /* shorthand */
@@ -435,7 +435,7 @@
 static void set_ref_in_list __ARGS((list_T *l, int copyID));
 static void set_ref_in_item __ARGS((typval_T *tv, int copyID));
 static void dict_unref __ARGS((dict_T *d));
-static void dict_free __ARGS((dict_T *d));
+static void dict_free __ARGS((dict_T *d, int recurse));
 static dictitem_T *dictitem_alloc __ARGS((char_u *key));
 static dictitem_T *dictitem_copy __ARGS((dictitem_T *org));
 static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item));
@@ -454,7 +454,7 @@
 static char_u *deref_func_name __ARGS((char_u *name, int *lenp));
 static int get_func_tv __ARGS((char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict));
 static int call_func __ARGS((char_u *name, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict));
-static void emsg_funcname __ARGS((char *msg, char_u *name));
+static void emsg_funcname __ARGS((char *ermsg, char_u *name));
 
 static void f_add __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_append __ARGS((typval_T *argvars, typval_T *rettv));
@@ -622,6 +622,7 @@
 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_settabwinvar __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_shellescape __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv));
@@ -701,6 +702,7 @@
 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string));
 static void set_var __ARGS((char_u *name, typval_T *varp, int copy));
 static int var_check_ro __ARGS((int flags, char_u *name));
+static int var_check_fixed __ARGS((int flags, char_u *name));
 static int tv_check_lock __ARGS((int lock, char_u *name));
 static void copy_tv __ARGS((typval_T *from, typval_T *to));
 static int item_copy __ARGS((typval_T *from, typval_T *to, int deep, int copyID));
@@ -2260,7 +2262,7 @@
 	    EMSG(_(e_letunexp));
 	else
 	{
-	    char_u	*tofree = NULL;
+	    char_u	*ptofree = NULL;
 	    char_u	*s;
 
 	    p = get_tv_string_chk(tv);
@@ -2269,7 +2271,7 @@
 		s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE);
 		if (s != NULL)
 		{
-		    p = tofree = concat_str(s, p);
+		    p = ptofree = concat_str(s, p);
 		    vim_free(s);
 		}
 	    }
@@ -2278,7 +2280,7 @@
 		write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE);
 		arg_end = arg + 1;
 	    }
-	    vim_free(tofree);
+	    vim_free(ptofree);
 	}
     }
 
@@ -3125,7 +3127,12 @@
     funcdict_T	fudi;
 
     tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi);
-    vim_free(fudi.fd_newkey);
+    if (fudi.fd_newkey != NULL)
+    {
+	/* Still need to give an error message for missing key. */
+	EMSG2(_(e_dictkey), fudi.fd_newkey);
+	vim_free(fudi.fd_newkey);
+    }
     if (tofree == NULL)
 	return;
 
@@ -3177,9 +3184,18 @@
 	    failed = TRUE;
 	    break;
 	}
+
+	/* Handle a function returning a Funcref, Dictionary or List. */
+	if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL)
+	{
+	    failed = TRUE;
+	    break;
+	}
+
 	clear_tv(&rettv);
 	if (doesrange || eap->skip)
 	    break;
+
 	/* Stop when immediately aborting on error, or when an interrupt
 	 * occurred or an exception was thrown but not caught.
 	 * get_func_tv() returned OK, so that the check for trailing
@@ -3364,6 +3380,8 @@
 	hi = hash_find(ht, varname);
 	if (!HASHITEM_EMPTY(hi))
 	{
+	    if (var_check_fixed(HI2DI(hi)->di_flags, name))
+		return FAIL;
 	    if (var_check_ro(HI2DI(hi)->di_flags, name))
 		return FAIL;
 	    delete_var(ht, hi);
@@ -4895,7 +4913,7 @@
 		    {
 			if (list_append_tv(l, &item->li_tv) == FAIL)
 			{
-			    list_free(l);
+			    list_free(l, TRUE);
 			    return FAIL;
 			}
 			item = item->li_next;
@@ -5295,7 +5313,7 @@
 	EMSG2(_("E697: Missing end of List ']': %s"), *arg);
 failret:
 	if (evaluate)
-	    list_free(l);
+	    list_free(l, TRUE);
 	return FAIL;
     }
 
@@ -5359,8 +5377,8 @@
 list_unref(l)
     list_T *l;
 {
-    if (l != NULL && l->lv_refcount != DEL_REFCOUNT && --l->lv_refcount <= 0)
-	list_free(l);
+    if (l != NULL && --l->lv_refcount <= 0)
+	list_free(l, TRUE);
 }
 
 /*
@@ -5368,14 +5386,12 @@
  * Ignores the reference count.
  */
     void
-list_free(l)
-    list_T *l;
+list_free(l, recurse)
+    list_T  *l;
+    int	    recurse;	/* Free Lists and Dictionaries recursively. */
 {
     listitem_T *item;
 
-    /* Avoid that recursive reference to the list frees us again. */
-    l->lv_refcount = DEL_REFCOUNT;
-
     /* Remove the list from the list of lists for garbage collection. */
     if (l->lv_used_prev == NULL)
 	first_list = l->lv_used_next;
@@ -5388,7 +5404,10 @@
     {
 	/* Remove the item before deleting it. */
 	l->lv_first = item->li_next;
-	listitem_free(item);
+	if (recurse || (item->li_tv.v_type != VAR_LIST
+					   && item->li_tv.v_type != VAR_DICT))
+	    clear_tv(&item->li_tv);
+	vim_free(item);
     }
     vim_free(l);
 }
@@ -5448,6 +5467,8 @@
 {
     listitem_T	*item1, *item2;
 
+    if (l1 == l2)
+	return TRUE;
     if (list_len(l1) != list_len(l2))
 	return FALSE;
 
@@ -5484,6 +5505,8 @@
     dictitem_T	*item2;
     int		todo;
 
+    if (d1 == d2)
+	return TRUE;
     if (dict_len(d1) != dict_len(d2))
 	return FALSE;
 
@@ -5516,19 +5539,29 @@
 {
     char_u	buf1[NUMBUFLEN], buf2[NUMBUFLEN];
     char_u	*s1, *s2;
+    static int  recursive = 0;	    /* cach recursive loops */
+    int		r;
 
     if (tv1->v_type != tv2->v_type)
 	return FALSE;
+    /* Catch lists and dicts that have an endless loop by limiting
+     * recursiveness to 1000.  We guess they are equal then. */
+    if (recursive >= 1000)
+	return TRUE;
 
     switch (tv1->v_type)
     {
 	case VAR_LIST:
-	    /* recursive! */
-	    return list_equal(tv1->vval.v_list, tv2->vval.v_list, ic);
+	    ++recursive;
+	    r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic);
+	    --recursive;
+	    return r;
 
 	case VAR_DICT:
-	    /* recursive! */
-	    return dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic);
+	    ++recursive;
+	    r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic);
+	    --recursive;
+	    return r;
 
 	case VAR_FUNC:
 	    return (tv1->vval.v_string != NULL
@@ -6059,6 +6092,10 @@
     tabpage_T	*tp;
 #endif
 
+    /* Only do this once. */
+    want_garbage_collect = FALSE;
+    may_garbage_collect = FALSE;
+
     /*
      * 1. Go through all accessible variables and mark all lists and dicts
      *    with copyID.
@@ -6097,7 +6134,10 @@
     for (dd = first_dict; dd != NULL; )
 	if (dd->dv_copyID != copyID)
 	{
-	    dict_free(dd);
+	    /* Free the Dictionary and ordinary items it contains, but don't
+	     * recurse into Lists and Dictionaries, they will be in the list
+	     * of dicts or list of lists. */
+	    dict_free(dd, FALSE);
 	    did_free = TRUE;
 
 	    /* restart, next dict may also have been freed */
@@ -6114,7 +6154,10 @@
     for (ll = first_list; ll != NULL; )
 	if (ll->lv_copyID != copyID && ll->lv_watch == NULL)
 	{
-	    list_free(ll);
+	    /* Free the List and ordinary items it contains, but don't recurse
+	     * into Lists and Dictionaries, they will be in the list of dicts
+	     * or list of lists. */
+	    list_free(ll, FALSE);
 	    did_free = TRUE;
 
 	    /* restart, next list may also have been freed */
@@ -6207,11 +6250,12 @@
     d = (dict_T *)alloc(sizeof(dict_T));
     if (d != NULL)
     {
-	/* Add the list to the hashtable for garbage collection. */
+	/* Add the list to the list of dicts for garbage collection. */
 	if (first_dict != NULL)
 	    first_dict->dv_used_prev = d;
 	d->dv_used_next = first_dict;
 	d->dv_used_prev = NULL;
+	first_dict = d;
 
 	hash_init(&d->dv_hashtab);
 	d->dv_lock = 0;
@@ -6229,8 +6273,8 @@
 dict_unref(d)
     dict_T *d;
 {
-    if (d != NULL && d->dv_refcount != DEL_REFCOUNT && --d->dv_refcount <= 0)
-	dict_free(d);
+    if (d != NULL && --d->dv_refcount <= 0)
+	dict_free(d, TRUE);
 }
 
 /*
@@ -6238,16 +6282,14 @@
  * Ignores the reference count.
  */
     static void
-dict_free(d)
-    dict_T *d;
+dict_free(d, recurse)
+    dict_T  *d;
+    int	    recurse;	/* Free Lists and Dictionaries recursively. */
 {
     int		todo;
     hashitem_T	*hi;
     dictitem_T	*di;
 
-    /* Avoid that recursive reference to the dict frees us again. */
-    d->dv_refcount = DEL_REFCOUNT;
-
     /* Remove the dict from the list of dicts for garbage collection. */
     if (d->dv_used_prev == NULL)
 	first_dict = d->dv_used_next;
@@ -6267,7 +6309,10 @@
 	     * something recursive causing trouble. */
 	    di = HI2DI(hi);
 	    hash_remove(&d->dv_hashtab, hi);
-	    dictitem_free(di);
+	    if (recurse || (di->di_tv.v_type != VAR_LIST
+					     && di->di_tv.v_type != VAR_DICT))
+		clear_tv(&di->di_tv);
+	    vim_free(di);
 	    --todo;
 	}
     }
@@ -6718,7 +6763,7 @@
 	EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg);
 failret:
 	if (evaluate)
-	    dict_free(d);
+	    dict_free(d, TRUE);
 	return FAIL;
     }
 
@@ -7139,6 +7184,7 @@
     {"setreg",		2, 3, f_setreg},
     {"settabwinvar",	4, 4, f_settabwinvar},
     {"setwinvar",	3, 3, f_setwinvar},
+    {"shellescape",	1, 1, f_shellescape},
     {"simplify",	1, 1, f_simplify},
     {"sort",		1, 2, f_sort},
     {"soundfold",	1, 1, f_soundfold},
@@ -7595,8 +7641,8 @@
  * Give an error message with a function name.  Handle <SNR> things.
  */
     static void
-emsg_funcname(msg, name)
-    char	*msg;
+emsg_funcname(ermsg, name)
+    char	*ermsg;
     char_u	*name;
 {
     char_u	*p;
@@ -7605,7 +7651,7 @@
 	p = concat_str((char_u *)"<SNR>", name + 3);
     else
 	p = name;
-    EMSG2(_(msg), p);
+    EMSG2(_(ermsg), p);
     if (p != name)
 	vim_free(p);
 }
@@ -8252,6 +8298,12 @@
 	EMSG(_("E785: complete() can only be used in Insert mode"));
 	return;
     }
+
+    /* Check for undo allowed here, because if something was already inserted
+     * the line was already saved for undo and this check isn't done. */
+    if (!undo_allowed())
+	return;
+
     if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL)
     {
 	EMSG(_(e_invarg));
@@ -9173,25 +9225,25 @@
     typval_T	save_key;
     int		rem;
     int		todo;
-    char_u	*msg = map ? (char_u *)"map()" : (char_u *)"filter()";
+    char_u	*ermsg = map ? (char_u *)"map()" : (char_u *)"filter()";
     int		save_did_emsg;
 
     rettv->vval.v_number = 0;
     if (argvars[0].v_type == VAR_LIST)
     {
 	if ((l = argvars[0].vval.v_list) == NULL
-		|| (map && tv_check_lock(l->lv_lock, msg)))
+		|| (map && tv_check_lock(l->lv_lock, ermsg)))
 	    return;
     }
     else if (argvars[0].v_type == VAR_DICT)
     {
 	if ((d = argvars[0].vval.v_dict) == NULL
-		|| (map && tv_check_lock(d->dv_lock, msg)))
+		|| (map && tv_check_lock(d->dv_lock, ermsg)))
 	    return;
     }
     else
     {
-	EMSG2(_(e_listdictarg), msg);
+	EMSG2(_(e_listdictarg), ermsg);
 	return;
     }
 
@@ -9223,7 +9275,7 @@
 		{
 		    --todo;
 		    di = HI2DI(hi);
-		    if (tv_check_lock(di->di_tv.v_lock, msg))
+		    if (tv_check_lock(di->di_tv.v_lock, ermsg))
 			break;
 		    vimvars[VV_KEY].vv_str = vim_strsave(di->di_key);
 		    if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL
@@ -9242,7 +9294,7 @@
 	{
 	    for (li = l->lv_first; li != NULL; li = nli)
 	    {
-		if (tv_check_lock(li->li_tv.v_lock, msg))
+		if (tv_check_lock(li->li_tv.v_lock, ermsg))
 		    break;
 		nli = li->li_next;
 		if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL
@@ -9598,7 +9650,9 @@
     typval_T	*argvars;
     typval_T	*rettv;
 {
-    garbage_collect();
+    /* This is postponed until we are back at the toplevel, because we may be
+     * using Lists and Dicts internally.  E.g.: ":echo [garbagecollect()]". */
+    want_garbage_collect = TRUE;
 }
 
 /*
@@ -9792,6 +9846,9 @@
     varnumber_T		n;
     int			error = FALSE;
 
+    /* Position the cursor.  Needed after a message that ends in a space. */
+    windgoto(msg_row, msg_col);
+
     ++no_mapping;
     ++allow_keys;
     if (argvars[0].v_type == VAR_UNKNOWN)
@@ -9809,6 +9866,10 @@
     --no_mapping;
     --allow_keys;
 
+    vimvars[VV_MOUSE_WIN].vv_nr = 0;
+    vimvars[VV_MOUSE_LNUM].vv_nr = 0;
+    vimvars[VV_MOUSE_COL].vv_nr = 0;
+
     rettv->vval.v_number = n;
     if (IS_SPECIAL(n) || mod_mask != 0)
     {
@@ -9837,6 +9898,53 @@
 	temp[i++] = NUL;
 	rettv->v_type = VAR_STRING;
 	rettv->vval.v_string = vim_strsave(temp);
+
+#ifdef FEAT_MOUSE
+	if (n == K_LEFTMOUSE
+		|| n == K_LEFTMOUSE_NM
+		|| n == K_LEFTDRAG
+		|| n == K_LEFTRELEASE
+		|| n == K_LEFTRELEASE_NM
+		|| n == K_MIDDLEMOUSE
+		|| n == K_MIDDLEDRAG
+		|| n == K_MIDDLERELEASE
+		|| n == K_RIGHTMOUSE
+		|| n == K_RIGHTDRAG
+		|| n == K_RIGHTRELEASE
+		|| n == K_X1MOUSE
+		|| n == K_X1DRAG
+		|| n == K_X1RELEASE
+		|| n == K_X2MOUSE
+		|| n == K_X2DRAG
+		|| n == K_X2RELEASE
+		|| n == K_MOUSEDOWN
+		|| n == K_MOUSEUP)
+	{
+	    int		row = mouse_row;
+	    int		col = mouse_col;
+	    win_T	*win;
+	    linenr_T	lnum;
+# ifdef FEAT_WINDOWS
+	    win_T	*wp;
+# endif
+	    int		n = 1;
+
+	    if (row >= 0 && col >= 0)
+	    {
+		/* Find the window at the mouse coordinates and compute the
+		 * text position. */
+		win = mouse_find_win(&row, &col);
+		(void)mouse_comp_pos(win, &row, &col, &lnum);
+# ifdef FEAT_WINDOWS
+		for (wp = firstwin; wp != win; wp = wp->w_next)
+		    ++n;
+# endif
+		vimvars[VV_MOUSE_WIN].vv_nr = n;
+		vimvars[VV_MOUSE_LNUM].vv_nr = lnum;
+		vimvars[VV_MOUSE_COL].vv_nr = col + 1;
+	    }
+	}
+#endif
     }
 }
 
@@ -10412,20 +10520,14 @@
 
     if (win != NULL && varname != NULL)
     {
-	if (*varname == '&')	/* window-local-option */
-	{
-	    /* Set curwin to be our win, temporarily.  Also set curbuf, so
-	     * that we can get buffer-local options. */
-	    oldcurwin = curwin;
-	    curwin = win;
-	    curbuf = win->w_buffer;
+	/* Set curwin to be our win, temporarily.  Also set curbuf, so
+	 * that we can get buffer-local options. */
+	oldcurwin = curwin;
+	curwin = win;
+	curbuf = win->w_buffer;
 
+	if (*varname == '&')	/* window-local-option */
 	    get_option_tv(&varname, rettv, 1);
-
-	    /* restore previous notion of curwin */
-	    curwin = oldcurwin;
-	    curbuf = curwin->w_buffer;
-	}
 	else
 	{
 	    if (*varname == NUL)
@@ -10438,6 +10540,10 @@
 	    if (v != NULL)
 		copy_tv(&v->di_tv, rettv);
 	}
+
+	/* restore previous notion of curwin */
+	curwin = oldcurwin;
+	curbuf = curwin->w_buffer;
     }
 
     --emsg_off;
@@ -11312,14 +11418,19 @@
 
 static int inputsecret_flag = 0;
 
+static void get_user_input __ARGS((typval_T *argvars, typval_T *rettv, int inputdialog));
+
 /*
- * "input()" function
- *     Also handles inputsecret() when inputsecret is set.
+ * This function is used by f_input() and f_inputdialog() functions. The third
+ * argument to f_input() specifies the type of completion to use at the
+ * prompt. The third argument to f_inputdialog() specifies the value to return
+ * when the user cancels the prompt.
  */
     static void
-f_input(argvars, rettv)
+get_user_input(argvars, rettv, inputdialog)
     typval_T	*argvars;
     typval_T	*rettv;
+    int		inputdialog;
 {
     char_u	*prompt = get_tv_string_chk(&argvars[0]);
     char_u	*p = NULL;
@@ -11369,10 +11480,10 @@
 	    if (defstr != NULL)
 		stuffReadbuffSpec(defstr);
 
-	    if (argvars[2].v_type != VAR_UNKNOWN)
+	    if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN)
 	    {
 		char_u	*xp_name;
-		int		xp_namelen;
+		int	xp_namelen;
 		long	argt;
 
 		rettv->vval.v_string = NULL;
@@ -11404,6 +11515,18 @@
 }
 
 /*
+ * "input()" function
+ *     Also handles inputsecret() when inputsecret is set.
+ */
+    static void
+f_input(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    get_user_input(argvars, rettv, FALSE);
+}
+
+/*
  * "inputdialog()" function
  */
     static void
@@ -11443,7 +11566,7 @@
     }
     else
 #endif
-	f_input(argvars, rettv);
+	get_user_input(argvars, rettv, TRUE);
 }
 
 /*
@@ -11471,6 +11594,7 @@
     }
 
     msg_start();
+    msg_row = Rows - 1;	/* for when 'cmdheight' > 1 */
     lines_left = Rows;	/* avoid more prompt */
     msg_scroll = TRUE;
     msg_clr_eos();
@@ -13250,7 +13374,7 @@
 	if (argvars[2].v_type != VAR_UNKNOWN)
 	    EMSG2(_(e_toomanyarg), "remove()");
 	else if ((d = argvars[0].vval.v_dict) != NULL
-		&& !tv_check_lock(d->dv_lock, (char_u *)"remove()"))
+		&& !tv_check_lock(d->dv_lock, (char_u *)"remove() argument"))
 	{
 	    key = get_tv_string_chk(&argvars[1]);
 	    if (key != NULL)
@@ -13270,7 +13394,7 @@
     else if (argvars[0].v_type != VAR_LIST)
 	EMSG2(_(e_listdictarg), "remove()");
     else if ((l = argvars[0].vval.v_list) != NULL
-	    && !tv_check_lock(l->lv_lock, (char_u *)"remove()"))
+	    && !tv_check_lock(l->lv_lock, (char_u *)"remove() argument"))
     {
 	int	    error = FALSE;
 
@@ -14157,11 +14281,7 @@
     typval_T	*rettv;
 {
     buf_T	*buf;
-#ifdef FEAT_AUTOCMD
     aco_save_T	aco;
-#else
-    buf_T	*save_curbuf;
-#endif
     char_u	*varname, *bufvarname;
     typval_T	*varp;
     char_u	nbuf[NUMBUFLEN];
@@ -14178,12 +14298,7 @@
     if (buf != NULL && varname != NULL && varp != NULL)
     {
 	/* set curbuf to be our buf, temporarily */
-#ifdef FEAT_AUTOCMD
 	aucmd_prepbuf(&aco, buf);
-#else
-	save_curbuf = curbuf;
-	curbuf = buf;
-#endif
 
 	if (*varname == '&')
 	{
@@ -14210,11 +14325,7 @@
 	}
 
 	/* reset notion of buffer */
-#ifdef FEAT_AUTOCMD
 	aucmd_restbuf(&aco);
-#else
-	curbuf = save_curbuf;
-#endif
     }
 }
 
@@ -14582,6 +14693,18 @@
 }
 
 /*
+ * "shellescape({string})" function
+ */
+    static void
+f_shellescape(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    rettv->vval.v_string = vim_strsave_shellescape(get_tv_string(&argvars[0]));
+    rettv->v_type = VAR_STRING;
+}
+
+/*
  * "simplify()" function
  */
     static void
@@ -16173,7 +16296,7 @@
 	curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant");
 	curwin->w_set_curswant = FALSE;
 
-	curwin->w_topline = get_dict_number(dict, (char_u *)"topline");
+	set_topline(curwin, get_dict_number(dict, (char_u *)"topline"));
 #ifdef FEAT_DIFF
 	curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill");
 #endif
@@ -16218,6 +16341,7 @@
 #ifdef FEAT_VIRTUALEDIT
     dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL);
 #endif
+    update_curswant();
     dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL);
 
     dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL);
@@ -16438,9 +16562,12 @@
     long	i = 0;
     long	n;
 
-    /* List must be: [fnum, lnum, col, coladd] */
-    if (arg->v_type != VAR_LIST || l == NULL
-				      || l->lv_len != (fnump == NULL ? 3 : 4))
+    /* List must be: [fnum, lnum, col, coladd], where "fnum" is only there
+     * when "fnump" isn't NULL and "coladd" is optional. */
+    if (arg->v_type != VAR_LIST
+	    || l == NULL
+	    || l->lv_len < (fnump == NULL ? 2 : 3)
+	    || l->lv_len > (fnump == NULL ? 3 : 4))
 	return FAIL;
 
     if (fnump != NULL)
@@ -16466,8 +16593,9 @@
 #ifdef FEAT_VIRTUALEDIT
     n = list_find_nr(l, i, NULL);
     if (n < 0)
-	return FAIL;
-    posp->coladd = n;
+	posp->coladd = 0;
+    else
+	posp->coladd = n;
 #endif
 
     return OK;
@@ -17759,6 +17887,13 @@
     }
     else		    /* add a new variable */
     {
+	/* Can't add "v:" variable. */
+	if (ht == &vimvarht)
+	{
+	    EMSG2(_(e_illvar), name);
+	    return;
+	}
+
 	/* Make sure the variable name is valid. */
 	for (p = varname; *p != NUL; ++p)
 	    if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))
@@ -17792,7 +17927,7 @@
 }
 
 /*
- * Return TRUE if di_flags "flags" indicate read-only variable "name".
+ * Return TRUE if di_flags "flags" indicates variable "name" is read-only.
  * Also give an error message.
  */
     static int
@@ -17814,6 +17949,23 @@
 }
 
 /*
+ * Return TRUE if di_flags "flags" indicates variable "name" is fixed.
+ * Also give an error message.
+ */
+    static int
+var_check_fixed(flags, name)
+    int		flags;
+    char_u	*name;
+{
+    if (flags & DI_FLAGS_FIX)
+    {
+	EMSG2(_("E795: Cannot delete variable %s"), name);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/*
  * Return TRUE if typeval "tv" is set to be locked (immutable).
  * Also give an error message, using "name".
  */
@@ -18396,12 +18548,14 @@
 
     if (!eap->skip)
     {
-	/* Check the name of the function. */
+	/* Check the name of the function.  Unless it's a dictionary function
+	 * (that we are overwriting). */
 	if (name != NULL)
 	    arg = name;
 	else
 	    arg = fudi.fd_newkey;
-	if (arg != NULL)
+	if (arg != NULL && (fudi.fd_di == NULL
+				     || fudi.fd_di->di_tv.v_type != VAR_FUNC))
 	{
 	    if (*arg == K_SPECIAL)
 		j = 3;
@@ -18786,6 +18940,7 @@
 		if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL)
 		{
 		    vim_free(fudi.fd_di);
+		    vim_free(fp);
 		    goto erret;
 		}
 	    }
@@ -18963,7 +19118,8 @@
     else if (lead > 0)
     {
 	lead = 3;
-	if (eval_fname_sid(lv.ll_exp_name != NULL ? lv.ll_exp_name : *pp))
+	if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name))
+						       || eval_fname_sid(*pp))
 	{
 	    /* It's "s:" or "<SID>" */
 	    if (current_SID <= 0)
@@ -19618,6 +19774,7 @@
     char_u	*name;
 #ifdef FEAT_PROFILE
     proftime_T	wait_start;
+    proftime_T	call_start;
 #endif
 
     /* If depth of calling is getting too high, don't execute the function */
@@ -19685,6 +19842,7 @@
     v->di_tv.vval.v_list = &fc.l_varlist;
     vim_memset(&fc.l_varlist, 0, sizeof(list_T));
     fc.l_varlist.lv_refcount = 99999;
+    fc.l_varlist.lv_lock = VAR_FIXED;
 
     /*
      * Set a:firstline to "firstline" and a:lastline to "lastline".
@@ -19761,7 +19919,7 @@
 	    if (p_verbose >= 14)
 	    {
 		char_u	buf[MSG_BUF_LEN];
-		char_u	numbuf[NUMBUFLEN];
+		char_u	numbuf2[NUMBUFLEN];
 		char_u	*tofree;
 
 		msg_puts((char_u *)"(");
@@ -19773,8 +19931,8 @@
 			msg_outnum((long)argvars[i].vval.v_number);
 		    else
 		    {
-			trunc_string(tv2string(&argvars[i], &tofree, numbuf, 0),
-							    buf, MSG_BUF_CLEN);
+			trunc_string(tv2string(&argvars[i], &tofree,
+					      numbuf2, 0), buf, MSG_BUF_CLEN);
 			msg_puts(buf);
 			vim_free(tofree);
 		    }
@@ -19796,7 +19954,7 @@
 		       || (fc.caller != NULL && &fc.caller->func->uf_profiling))
 	{
 	    ++fp->uf_tm_count;
-	    profile_start(&fp->uf_tm_start);
+	    profile_start(&call_start);
 	    profile_zero(&fp->uf_tm_children);
 	}
 	script_prof_save(&wait_start);
@@ -19826,14 +19984,14 @@
     if (do_profiling == PROF_YES && (fp->uf_profiling
 		    || (fc.caller != NULL && &fc.caller->func->uf_profiling)))
     {
-	profile_end(&fp->uf_tm_start);
-	profile_sub_wait(&wait_start, &fp->uf_tm_start);
-	profile_add(&fp->uf_tm_total, &fp->uf_tm_start);
-	profile_self(&fp->uf_tm_self, &fp->uf_tm_start, &fp->uf_tm_children);
+	profile_end(&call_start);
+	profile_sub_wait(&wait_start, &call_start);
+	profile_add(&fp->uf_tm_total, &call_start);
+	profile_self(&fp->uf_tm_self, &call_start, &fp->uf_tm_children);
 	if (fc.caller != NULL && &fc.caller->func->uf_profiling)
 	{
-	    profile_add(&fc.caller->func->uf_tm_children, &fp->uf_tm_start);
-	    profile_add(&fc.caller->func->uf_tml_children, &fp->uf_tm_start);
+	    profile_add(&fc.caller->func->uf_tm_children, &call_start);
+	    profile_add(&fc.caller->func->uf_tml_children, &call_start);
 	}
     }
 #endif
@@ -19852,13 +20010,13 @@
 	else
 	{
 	    char_u	buf[MSG_BUF_LEN];
-	    char_u	numbuf[NUMBUFLEN];
+	    char_u	numbuf2[NUMBUFLEN];
 	    char_u	*tofree;
 
 	    /* The value may be very long.  Skip the middle part, so that we
 	     * have some idea how it starts and ends. smsg() would always
 	     * truncate it at the end. */
-	    trunc_string(tv2string(fc.rettv, &tofree, numbuf, 0),
+	    trunc_string(tv2string(fc.rettv, &tofree, numbuf2, 0),
 							   buf, MSG_BUF_CLEN);
 	    smsg((char_u *)_("%s returning %s"), sourcing_name, buf);
 	    vim_free(tofree);
diff -Naur vim70.orig/src/ex_cmds2.c vim70/src/ex_cmds2.c
--- vim70.orig/src/ex_cmds2.c	2006-04-17 03:19:07.000000000 -0700
+++ vim70/src/ex_cmds2.c	2006-11-29 16:09:58.000000000 -0800
@@ -3648,13 +3648,13 @@
  * Return FALSE when not sourcing a file.
  */
     int
-source_finished(getline, cookie)
-    char_u	*(*getline) __ARGS((int, void *, int));
+source_finished(fgetline, cookie)
+    char_u	*(*fgetline) __ARGS((int, void *, int));
     void	*cookie;
 {
-    return (getline_equal(getline, cookie, getsourceline)
+    return (getline_equal(fgetline, cookie, getsourceline)
 	    && ((struct source_cookie *)getline_cookie(
-						 getline, cookie))->finished);
+						fgetline, cookie))->finished);
 }
 #endif
 
diff -Naur vim70.orig/src/ex_cmds.c vim70/src/ex_cmds.c
--- vim70.orig/src/ex_cmds.c	2006-04-22 11:56:56.000000000 -0700
+++ vim70/src/ex_cmds.c	2006-11-29 16:10:04.000000000 -0800
@@ -95,7 +95,10 @@
 		_("<%s>%s%s  %d,  Hex %02x,  Octal %03o"),
 					   transchar(c), buf1, buf2, c, c, c);
 #ifdef FEAT_MBYTE
-	c = cc[ci++];
+	if (enc_utf8)
+	    c = cc[ci++];
+	else
+	    c = 0;
 #endif
     }
 
@@ -108,7 +111,7 @@
 	if (len > 0)
 	    IObuff[len++] = ' ';
 	IObuff[len++] = '<';
-	if (utf_iscomposing(c)
+	if (enc_utf8 && utf_iscomposing(c)
 # ifdef USE_GUI
 		&& !gui.in_use
 # endif
@@ -120,7 +123,10 @@
 				    : _("> %d, Hex %08x, Octal %o"), c, c, c);
 	if (ci == MAX_MCO)
 	    break;
-	c = cc[ci++];
+	if (enc_utf8)
+	    c = cc[ci++];
+	else
+	    c = 0;
     }
 #endif
 
@@ -185,6 +191,7 @@
 	    new_indent = indent;
 	else
 	{
+	    has_tab = FALSE;	/* avoid uninit warnings */
 	    len = linelen(eap->cmdidx == CMD_right ? &has_tab
 						   : NULL) - get_indent();
 
@@ -1772,10 +1779,9 @@
 				? (st_old.st_mode & 0020)
 				: (st_old.st_mode & 0002))))
 	{
-	    int	tt;
+	    int	tt = msg_didany;
 
 	    /* avoid a wait_return for this message, it's annoying */
-	    tt = msg_didany;
 	    EMSG2(_("E137: Viminfo file is not writable: %s"), fname);
 	    msg_didany = tt;
 	    fclose(fp_in);
@@ -2458,6 +2464,8 @@
 #ifdef FEAT_AUTOCMD
 	apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf);
 #endif
+	/* Change directories when the 'acd' option is set. */
+	DO_AUTOCHDIR
     }
     /* print full file name if :cd used */
     fileinfo(FALSE, FALSE, eap->forceit);
@@ -2675,8 +2683,13 @@
 				 eap, eap->append, eap->forceit, TRUE, FALSE);
 
 	/* After ":saveas fname" reset 'readonly'. */
-	if (eap->cmdidx == CMD_saveas && retval == OK)
-	    curbuf->b_p_ro = FALSE;
+	if (eap->cmdidx == CMD_saveas)
+	{
+	    if (retval == OK)
+		curbuf->b_p_ro = FALSE;
+	    /* Change directories when the 'acd' option is set. */
+	    DO_AUTOCHDIR
+	}
     }
 
 theend:
@@ -3547,11 +3560,9 @@
 	foldUpdateAll(curwin);
 #endif
 
-#ifdef FEAT_AUTOCHDIR
-	if (p_acd && curbuf->b_ffname != NULL
-				     && vim_chdirfile(curbuf->b_ffname) == OK)
-	    shorten_fnames(TRUE);
-#endif
+	/* Change directories when the 'acd' option is set. */
+	DO_AUTOCHDIR
+
 	/*
 	 * Careful: open_buffer() and apply_autocmds() may change the current
 	 * buffer and window.
@@ -3718,12 +3729,8 @@
     if (p_im)
 	need_start_insertmode = TRUE;
 
-#ifdef FEAT_AUTOCHDIR
-    /* Change directories when the acd option is set on. */
-    if (p_acd && curbuf->b_ffname != NULL
-				     && vim_chdirfile(curbuf->b_ffname) == OK)
-	shorten_fnames(TRUE);
-#endif
+    /* Change directories when the 'acd' option is set. */
+    DO_AUTOCHDIR
 
 #if defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG)
     if (gui.in_use && curbuf->b_ffname != NULL)
diff -Naur vim70.orig/src/ex_cmds.h vim70/src/ex_cmds.h
--- vim70.orig/src/ex_cmds.h	2006-04-07 02:44:46.000000000 -0700
+++ vim70/src/ex_cmds.h	2006-11-29 16:09:53.000000000 -0800
@@ -262,7 +262,7 @@
 EX(CMD_comclear,	"comclear",	ex_comclear,
 			TRLBAR|CMDWIN),
 EX(CMD_compiler,	"compiler",	ex_compiler,
-			BANG|TRLBAR|WORD1),
+			BANG|TRLBAR|WORD1|CMDWIN),
 EX(CMD_continue,	"continue",	ex_continue,
 			TRLBAR|SBOXOK|CMDWIN),
 EX(CMD_confirm,		"confirm",	ex_wrongmodifier,
diff -Naur vim70.orig/src/ex_docmd.c vim70/src/ex_docmd.c
--- vim70.orig/src/ex_docmd.c	2006-05-05 09:33:19.000000000 -0700
+++ vim70/src/ex_docmd.c	2006-11-29 16:10:23.000000000 -0800
@@ -58,9 +58,9 @@
 #endif
 
 #ifdef FEAT_EVAL
-static char_u	*do_one_cmd __ARGS((char_u **, int, struct condstack *, char_u *(*getline)(int, void *, int), void *cookie));
+static char_u	*do_one_cmd __ARGS((char_u **, int, struct condstack *, char_u *(*fgetline)(int, void *, int), void *cookie));
 #else
-static char_u	*do_one_cmd __ARGS((char_u **, int, char_u *(*getline)(int, void *, int), void *cookie));
+static char_u	*do_one_cmd __ARGS((char_u **, int, char_u *(*fgetline)(int, void *, int), void *cookie));
 static int	if_level = 0;		/* depth in :if */
 #endif
 static char_u	*find_command __ARGS((exarg_T *eap, int *full));
@@ -831,10 +831,13 @@
 
     /*
      * If requested, store and reset the global values controlling the
-     * exception handling (used when debugging).
+     * exception handling (used when debugging).  Otherwise clear it to avoid
+     * a bogus compiler warning when the optimizer uses inline functions...
      */
-    else if (flags & DOCMD_EXCRESET)
+    if (flags & DOCMD_EXCRESET)
 	save_dbg_stuff(&debug_saved);
+    else
+	memset(&debug_saved, 0, 1);
 
     initial_trylevel = trylevel;
 
@@ -1574,24 +1577,24 @@
 #endif
 
 /*
- * If "getline" is get_loop_line(), return TRUE if the getline it uses equals
- * "func".  * Otherwise return TRUE when "getline" equals "func".
+ * If "fgetline" is get_loop_line(), return TRUE if the getline it uses equals
+ * "func".  * Otherwise return TRUE when "fgetline" equals "func".
  */
 /*ARGSUSED*/
     int
-getline_equal(getline, cookie, func)
-    char_u	*(*getline) __ARGS((int, void *, int));
-    void	*cookie;		/* argument for getline() */
+getline_equal(fgetline, cookie, func)
+    char_u	*(*fgetline) __ARGS((int, void *, int));
+    void	*cookie;		/* argument for fgetline() */
     char_u	*(*func) __ARGS((int, void *, int));
 {
 #ifdef FEAT_EVAL
     char_u		*(*gp) __ARGS((int, void *, int));
     struct loop_cookie *cp;
 
-    /* When "getline" is "get_loop_line()" use the "cookie" to find the
+    /* When "fgetline" is "get_loop_line()" use the "cookie" to find the
      * function that's orignally used to obtain the lines.  This may be nested
      * several levels. */
-    gp = getline;
+    gp = fgetline;
     cp = (struct loop_cookie *)cookie;
     while (gp == get_loop_line)
     {
@@ -1600,29 +1603,29 @@
     }
     return gp == func;
 #else
-    return getline == func;
+    return fgetline == func;
 #endif
 }
 
 #if defined(FEAT_EVAL) || defined(FEAT_MBYTE) || defined(PROTO)
 /*
- * If "getline" is get_loop_line(), return the cookie used by the original
+ * If "fgetline" is get_loop_line(), return the cookie used by the original
  * getline function.  Otherwise return "cookie".
  */
 /*ARGSUSED*/
     void *
-getline_cookie(getline, cookie)
-    char_u	*(*getline) __ARGS((int, void *, int));
-    void	*cookie;		/* argument for getline() */
+getline_cookie(fgetline, cookie)
+    char_u	*(*fgetline) __ARGS((int, void *, int));
+    void	*cookie;		/* argument for fgetline() */
 {
 # ifdef FEAT_EVAL
     char_u		*(*gp) __ARGS((int, void *, int));
     struct loop_cookie *cp;
 
-    /* When "getline" is "get_loop_line()" use the "cookie" to find the
+    /* When "fgetline" is "get_loop_line()" use the "cookie" to find the
      * cookie that's orignally used to obtain the lines.  This may be nested
      * several levels. */
-    gp = getline;
+    gp = fgetline;
     cp = (struct loop_cookie *)cookie;
     while (gp == get_loop_line)
     {
@@ -1648,7 +1651,7 @@
  * 5. parse arguments
  * 6. switch on command name
  *
- * Note: "getline" can be NULL.
+ * Note: "fgetline" can be NULL.
  *
  * This function may be called recursively!
  */
@@ -1663,14 +1666,14 @@
 #ifdef FEAT_EVAL
 			    cstack,
 #endif
-				    getline, cookie)
+				    fgetline, cookie)
     char_u		**cmdlinep;
     int			sourcing;
 #ifdef FEAT_EVAL
     struct condstack	*cstack;
 #endif
-    char_u		*(*getline) __ARGS((int, void *, int));
-    void		*cookie;		/* argument for getline() */
+    char_u		*(*fgetline) __ARGS((int, void *, int));
+    void		*cookie;		/* argument for fgetline() */
 {
     char_u		*p;
     linenr_T		lnum;
@@ -1698,7 +1701,7 @@
     if (quitmore
 #ifdef FEAT_EVAL
 	    /* avoid that a function call in 'statusline' does this */
-	    && !getline_equal(getline, cookie, get_func_line)
+	    && !getline_equal(fgetline, cookie, get_func_line)
 #endif
 	    )
 	--quitmore;
@@ -1710,6 +1713,10 @@
     save_cmdmod = cmdmod;
     vim_memset(&cmdmod, 0, sizeof(cmdmod));
 
+    /* "#!anything" is handled like a comment. */
+    if ((*cmdlinep)[0] == '#' && (*cmdlinep)[1] == '!')
+	goto doend;
+
     /*
      * Repeat until no more command modifiers are found.
      */
@@ -1724,8 +1731,8 @@
 
 	/* in ex mode, an empty line works like :+ */
 	if (*ea.cmd == NUL && exmode_active
-			&& (getline_equal(getline, cookie, getexmodeline)
-			    || getline_equal(getline, cookie, getexline))
+			&& (getline_equal(fgetline, cookie, getexmodeline)
+			    || getline_equal(fgetline, cookie, getexline))
 			&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
 	{
 	    ea.cmd = (char_u *)"+";
@@ -1914,9 +1921,9 @@
     /* Count this line for profiling if ea.skip is FALSE. */
     if (do_profiling == PROF_YES && !ea.skip)
     {
-	if (getline_equal(getline, cookie, get_func_line))
-	    func_line_exec(getline_cookie(getline, cookie));
-	else if (getline_equal(getline, cookie, getsourceline))
+	if (getline_equal(fgetline, cookie, get_func_line))
+	    func_line_exec(getline_cookie(fgetline, cookie));
+	else if (getline_equal(fgetline, cookie, getsourceline))
 	    script_line_exec();
     }
 #endif
@@ -2585,7 +2592,7 @@
  * The "ea" structure holds the arguments that can be used.
  */
     ea.cmdlinep = cmdlinep;
-    ea.getline = getline;
+    ea.getline = fgetline;
     ea.cookie = cookie;
 #ifdef FEAT_EVAL
     ea.cstack = cstack;
@@ -2623,9 +2630,9 @@
 	do_throw(cstack);
     else if (check_cstack)
     {
-	if (source_finished(getline, cookie))
+	if (source_finished(fgetline, cookie))
 	    do_finish(&ea, TRUE);
-	else if (getline_equal(getline, cookie, get_func_line)
+	else if (getline_equal(fgetline, cookie, get_func_line)
 						   && current_func_returned())
 	    do_return(&ea, TRUE, FALSE, NULL);
     }
@@ -6289,7 +6296,6 @@
     exarg_T	*eap;
 {
     tabpage_T	*tp;
-    int		h = tabline_height();
 
 # ifdef FEAT_CMDWIN
     if (cmdwin_type != 0)
@@ -6321,9 +6327,6 @@
 	       )
 		tabpage_close(eap->forceit);
 	}
-
-    if (h != tabline_height())
-	shell_new_rows();
 }
 
 /*
@@ -6335,7 +6338,6 @@
 {
     tabpage_T	*tp;
     int		done;
-    int		h = tabline_height();
 
 # ifdef FEAT_CMDWIN
     if (cmdwin_type != 0)
@@ -6364,9 +6366,6 @@
 		    break;
 	    }
 	}
-
-    if (h != tabline_height())
-	shell_new_rows();
 }
 
 /*
@@ -6390,6 +6389,8 @@
 /*
  * Close tab page "tp", which is not the current tab page.
  * Note that autocommands may make "tp" invalid.
+ * Also takes care of the tab pages line disappearing when closing the
+ * last-but-one tab page.
  */
     void
 tabpage_close_other(tp, forceit)
@@ -6398,6 +6399,7 @@
 {
     int		done = 0;
     win_T	*wp;
+    int		h = tabline_height();
 
     /* Limit to 1000 windows, autocommands may add a window while we close
      * one.  OK, so I'm paranoid... */
@@ -6411,7 +6413,10 @@
 	if (!valid_tabpage(tp) || tp->tp_firstwin == wp)
 	    break;
     }
+
     redraw_tabline = TRUE;
+    if (h != tabline_height())
+	shell_new_rows();
 }
 
 /*
@@ -8214,8 +8219,9 @@
     c = *eap->arg;
     if (c == NUL || (c == '*' && *eap->cmd == '*'))
 	c = '@';
-    /* put the register in mapbuf */
-    if (do_execreg(c, TRUE, vim_strchr(p_cpo, CPO_EXECBUF) != NULL) == FAIL)
+    /* Put the register in the typeahead buffer with the "silent" flag. */
+    if (do_execreg(c, TRUE, vim_strchr(p_cpo, CPO_EXECBUF) != NULL, TRUE)
+								      == FAIL)
     {
 	beep_flush();
     }
@@ -8365,6 +8371,7 @@
 	    if (ASCII_ISALPHA(*arg)
 # ifdef FEAT_CLIPBOARD
 		    || *arg == '*'
+		    || *arg == '+'
 # endif
 		    || *arg == '"')
 	    {
@@ -8375,6 +8382,7 @@
 			 (islower(redir_reg)
 # ifdef FEAT_CLIPBOARD
 			    || redir_reg == '*'
+			    || redir_reg == '+'
 # endif
 			    || redir_reg == '"'))
 		{
@@ -8417,6 +8425,15 @@
 	else
 	    EMSG2(_(e_invarg2), eap->arg);
     }
+
+    /* Make sure redirection is not off.  Can happen for cmdline completion
+     * that indirectly invokes a command to catch its output. */
+    if (redir_fd != NULL
+#ifdef FEAT_EVAL
+			  || redir_reg || redir_vname
+#endif
+							)
+	redir_off = FALSE;
 }
 
 /*
@@ -9629,7 +9646,8 @@
 #endif
 
 #ifdef FEAT_SESSION
-static int ses_winsizes __ARGS((FILE *fd, int restore_size));
+static int ses_winsizes __ARGS((FILE *fd, int restore_size,
+							win_T *tab_firstwin));
 static int ses_win_rec __ARGS((FILE *fd, frame_T *fr));
 static frame_T *ses_skipframe __ARGS((frame_T *fr));
 static int ses_do_frame __ARGS((frame_T *fr));
@@ -9655,8 +9673,9 @@
     win_T	*wp;
     char_u	*sname;
     win_T	*edited_win = NULL;
-    tabpage_T	*old_curtab = curtab;
     int		tabnr;
+    win_T	*tab_firstwin;
+    frame_T	*tab_topframe;
 
     if (ssop_flags & SSOP_BUFFERS)
 	only_save_windows = FALSE;		/* Save ALL buffers */
@@ -9764,14 +9783,33 @@
     /*
      * May repeat putting Windows for each tab, when "tabpages" is in
      * 'sessionoptions'.
+     * Don't use goto_tabpage(), it may change directory and trigger
+     * autocommands.
      */
+    tab_firstwin = firstwin;	/* first window in tab page "tabnr" */
+    tab_topframe = topframe;
     for (tabnr = 1; ; ++tabnr)
     {
+	int  need_tabnew = FALSE;
+
 	if ((ssop_flags & SSOP_TABPAGES))
 	{
-	    goto_tabpage(tabnr);
-	    if (tabnr > 1 && put_line(fd, "tabnew") == FAIL)
-		return FAIL;
+	    tabpage_T *tp = find_tabpage(tabnr);
+
+	    if (tp == NULL)
+		break;		/* done all tab pages */
+	    if (tp == curtab)
+	    {
+		tab_firstwin = firstwin;
+		tab_topframe = topframe;
+	    }
+	    else
+	    {
+		tab_firstwin = tp->tp_firstwin;
+		tab_topframe = tp->tp_topframe;
+	    }
+	    if (tabnr > 1)
+		need_tabnew = TRUE;
 	}
 
 	/*
@@ -9779,7 +9817,7 @@
 	 * is aborted we don't end up with a number of useless windows.
 	 * This may have side effects! (e.g., compressed or network file).
 	 */
-	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	for (wp = tab_firstwin; wp != NULL; wp = wp->w_next)
 	{
 	    if (ses_do_win(wp)
 		    && wp->w_buffer->b_ffname != NULL
@@ -9789,21 +9827,26 @@
 #endif
 		    )
 	    {
-		if (fputs("edit ", fd) < 0
+		if (fputs(need_tabnew ? "tabedit " : "edit ", fd) < 0
 			|| ses_fname(fd, wp->w_buffer, &ssop_flags) == FAIL)
 		    return FAIL;
+		need_tabnew = FALSE;
 		if (!wp->w_arg_idx_invalid)
 		    edited_win = wp;
 		break;
 	    }
 	}
 
+	/* If no file got edited create an empty tab page. */
+	if (need_tabnew && put_line(fd, "tabnew") == FAIL)
+	    return FAIL;
+
 	/*
 	 * Save current window layout.
 	 */
 	if (put_line(fd, "set splitbelow splitright") == FAIL)
 	    return FAIL;
-	if (ses_win_rec(fd, topframe) == FAIL)
+	if (ses_win_rec(fd, tab_topframe) == FAIL)
 	    return FAIL;
 	if (!p_sb && put_line(fd, "set nosplitbelow") == FAIL)
 	    return FAIL;
@@ -9815,7 +9858,7 @@
 	 * Remember the window number of the current window after restoring.
 	 */
 	nr = 0;
-	for (wp = firstwin; wp != NULL; wp = W_NEXT(wp))
+	for (wp = tab_firstwin; wp != NULL; wp = W_NEXT(wp))
 	{
 	    if (ses_do_win(wp))
 		++nr;
@@ -9838,13 +9881,13 @@
 	 */
 	if (put_line(fd, "set winheight=1 winwidth=1") == FAIL)
 	    return FAIL;
-	if (nr > 1 && ses_winsizes(fd, restore_size) == FAIL)
+	if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL)
 	    return FAIL;
 
 	/*
 	 * Restore the view of the window (options, file, cursor, etc.).
 	 */
-	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	for (wp = tab_firstwin; wp != NULL; wp = wp->w_next)
 	{
 	    if (!ses_do_win(wp))
 		continue;
@@ -9865,19 +9908,17 @@
 	 * Restore window sizes again after jumping around in windows, because
 	 * the current window has a minimum size while others may not.
 	 */
-	if (nr > 1 && ses_winsizes(fd, restore_size) == FAIL)
+	if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL)
 	    return FAIL;
 
 	/* Don't continue in another tab page when doing only the current one
 	 * or when at the last tab page. */
-	if (!(ssop_flags & SSOP_TABPAGES) || curtab->tp_next == NULL)
+	if (!(ssop_flags & SSOP_TABPAGES))
 	    break;
     }
 
     if (ssop_flags & SSOP_TABPAGES)
     {
-	if (valid_tabpage(old_curtab))
-	    goto_tabpage_tp(old_curtab);
 	if (fprintf(fd, "tabnext %d", tabpage_index(curtab)) < 0
 		|| put_eol(fd) == FAIL)
 	    return FAIL;
@@ -9913,16 +9954,17 @@
 }
 
     static int
-ses_winsizes(fd, restore_size)
+ses_winsizes(fd, restore_size, tab_firstwin)
     FILE	*fd;
     int		restore_size;
+    win_T	*tab_firstwin;
 {
     int		n = 0;
     win_T	*wp;
 
     if (restore_size && (ssop_flags & SSOP_WINSIZE))
     {
-	for (wp = firstwin; wp != NULL; wp = wp->w_next)
+	for (wp = tab_firstwin; wp != NULL; wp = wp->w_next)
 	{
 	    if (!ses_do_win(wp))
 		continue;
diff -Naur vim70.orig/src/ex_eval.c vim70/src/ex_eval.c
--- vim70.orig/src/ex_eval.c	2006-04-22 12:22:27.000000000 -0700
+++ vim70/src/ex_eval.c	2006-11-29 16:10:23.000000000 -0800
@@ -340,7 +340,7 @@
 
     /* If no exception is to be thrown or the conversion should be done after
      * returning to a previous invocation of do_one_cmd(), do nothing. */
-    if (*msg_list == NULL)
+    if (msg_list == NULL || *msg_list == NULL)
 	return;
 
     if (throw_exception(*msg_list, ET_ERROR, cmdname) == FAIL)
@@ -2026,8 +2026,11 @@
 
 	/* If an error was about to be converted to an exception when
 	 * enter_cleanup() was called, free the message list. */
-	free_msglist(*msg_list);
-	*msg_list = NULL;
+	if (msg_list != NULL)
+	{
+	    free_msglist(*msg_list);
+	    *msg_list = NULL;
+	}
     }
 
     /*
diff -Naur vim70.orig/src/ex_getln.c vim70/src/ex_getln.c
--- vim70.orig/src/ex_getln.c	2006-04-30 08:32:01.000000000 -0700
+++ vim70/src/ex_getln.c	2006-11-29 16:10:15.000000000 -0800
@@ -34,7 +34,7 @@
     int		xp_context;	/* type of expansion */
 # ifdef FEAT_EVAL
     char_u	*xp_arg;	/* user-defined expansion arg */
-    int		input_fn;	/* Invoked for input() function */
+    int		input_fn;	/* when TRUE Invoked for input() function */
 # endif
 };
 
@@ -86,7 +86,7 @@
 static void	draw_cmdline __ARGS((int start, int len));
 static void	save_cmdline __ARGS((struct cmdline_info *ccp));
 static void	restore_cmdline __ARGS((struct cmdline_info *ccp));
-static int	cmdline_paste __ARGS((int regname, int literally));
+static int	cmdline_paste __ARGS((int regname, int literally, int remcr));
 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
 static void	redrawcmd_preedit __ARGS((void));
 #endif
@@ -324,6 +324,9 @@
      */
     for (;;)
     {
+	redir_off = TRUE;	/* Don't redirect the typed command.
+				   Repeated, because a ":redir" inside
+				   completion may switch it on. */
 #ifdef USE_ON_FLY_SCROLL
 	dont_scroll = FALSE;	/* allow scrolling here */
 #endif
@@ -1113,7 +1116,7 @@
 #endif
 		if (c != ESC)	    /* use ESC to cancel inserting register */
 		{
-		    cmdline_paste(c, i == Ctrl_R);
+		    cmdline_paste(c, i == Ctrl_R, FALSE);
 
 #ifdef FEAT_EVAL
 		    /* When there was a serious error abort getting the
@@ -1228,16 +1231,16 @@
 			goto cmdline_not_changed;   /* Ignore mouse */
 # ifdef FEAT_CLIPBOARD
 		if (clip_star.available)
-		    cmdline_paste('*', TRUE);
+		    cmdline_paste('*', TRUE, TRUE);
 		else
 # endif
-		    cmdline_paste(0, TRUE);
+		    cmdline_paste(0, TRUE, TRUE);
 		redrawcmd();
 		goto cmdline_changed;
 
 # ifdef FEAT_DND
 	case K_DROP:
-		cmdline_paste('~', TRUE);
+		cmdline_paste('~', TRUE, FALSE);
 		redrawcmd();
 		goto cmdline_changed;
 # endif
@@ -1387,7 +1390,17 @@
 		    {
 			c = gchar_cursor();
 			if (c != NUL)
+			{
+			    if (c == firstc || vim_strchr((char_u *)(
+					    p_magic ? "\\^$.*[" : "\\^$"), c)
+								      != NULL)
+			    {
+				/* put a backslash before special characters */
+				stuffcharReadbuff(c);
+				c = '\\';
+			    }
 			    break;
+			}
 		    }
 		    goto cmdline_not_changed;
 		}
@@ -1753,6 +1766,11 @@
 		end_pos = curwin->w_cursor; /* shutup gcc 4 */
 
 	    validate_cursor();
+# ifdef FEAT_WINDOWS
+	    /* May redraw the status line to show the cursor position. */
+	    if (p_ru && curwin->w_status_height > 0)
+		curwin->w_redr_status = TRUE;
+# endif
 
 	    save_cmdline(&save_ccline);
 	    update_screen(SOME_VALID);
@@ -2360,7 +2378,7 @@
 {
     if ((State & CMDLINE)
 	    && xic != NULL
-	    && im_get_status()
+	    /* && im_get_status()  doesn't work when using SCIM */
 	    && !p_imdisable
 	    && im_is_preediting())
     {
@@ -2882,9 +2900,10 @@
  * return FAIL for failure, OK otherwise
  */
     static int
-cmdline_paste(regname, literally)
+cmdline_paste(regname, literally, remcr)
     int regname;
     int literally;	/* Insert text literally instead of "as typed" */
+    int remcr;		/* remove trailing CR */
 {
     long		i;
     char_u		*arg;
@@ -2960,7 +2979,7 @@
 	return OK;
     }
 
-    return cmdline_paste_reg(regname, literally);
+    return cmdline_paste_reg(regname, literally, remcr);
 }
 
 /*
@@ -4521,7 +4540,9 @@
     flags |= EW_FILE | EW_EXEC;
 
     /* For an absolute name we don't use $PATH. */
-    if ((pat[0] == '.' && (vim_ispathsep(pat[1])
+    if (mch_isFullName(pat))
+	path = (char_u *)" ";
+    else if ((pat[0] == '.' && (vim_ispathsep(pat[1])
 			    || (pat[1] == '.' && vim_ispathsep(pat[2])))))
 	path = (char_u *)".";
     else
@@ -4534,6 +4555,9 @@
     ga_init2(&ga, (int)sizeof(char *), 10);
     for (s = path; *s != NUL; s = e)
     {
+	if (*s == ' ')
+	    ++s;	/* Skip space used for absolute path name. */
+
 #if defined(MSDOS) || defined(MSWIN) || defined(OS2)
 	e = vim_strchr(s, ';');
 #else
@@ -5982,6 +6006,8 @@
     typestr[0] = cmdwin_type;
     typestr[1] = NUL;
     apply_autocmds(EVENT_CMDWINENTER, typestr, typestr, FALSE, curbuf);
+    if (restart_edit != 0)	/* autocmd with ":startinsert" */
+	stuffcharReadbuff(K_NOP);
 # endif
 
     i = RedrawingDisabled;
diff -Naur vim70.orig/src/fileio.c vim70/src/fileio.c
--- vim70.orig/src/fileio.c	2006-04-30 08:28:57.000000000 -0700
+++ vim70/src/fileio.c	2006-11-29 16:10:06.000000000 -0800
@@ -316,6 +316,9 @@
      * display the line. */
     ex_no_reprint = TRUE;
 
+    /* don't display the file info for another buffer now */
+    need_fileinfo = FALSE;
+
     /*
      * For Unix: Use the short file name whenever possible.
      * Avoids problems with networks and when directory names are changed.
@@ -6450,17 +6453,10 @@
     int		old_ro = buf->b_p_ro;
     buf_T	*savebuf;
     int		saved = OK;
-#ifdef FEAT_AUTOCMD
     aco_save_T	aco;
 
     /* set curwin/curbuf for "buf" and save some things */
     aucmd_prepbuf(&aco, buf);
-#else
-    buf_T	*save_curbuf = curbuf;
-
-    curbuf = buf;
-    curwin->w_buffer = buf;
-#endif
 
     /* We only want to read the text from the file, not reset the syntax
      * highlighting, clear marks, diff status, etc.  Force the fileformat
@@ -6573,14 +6569,9 @@
 	    curbuf->b_p_ro |= old_ro;
     }
 
-#ifdef FEAT_AUTOCMD
     /* restore curwin/curbuf and a few other things */
     aucmd_restbuf(&aco);
     /* Careful: autocommands may have made "buf" invalid! */
-#else
-    curwin->w_buffer = save_curbuf;
-    curbuf = save_curbuf;
-#endif
 }
 
 /*ARGSUSED*/
@@ -6992,6 +6983,7 @@
     {"FocusLost",	EVENT_FOCUSLOST},
     {"FuncUndefined",	EVENT_FUNCUNDEFINED},
     {"GUIEnter",	EVENT_GUIENTER},
+    {"GUIFailed",	EVENT_GUIFAILED},
     {"InsertChange",	EVENT_INSERTCHANGE},
     {"InsertEnter",	EVENT_INSERTENTER},
     {"InsertLeave",	EVENT_INSERTLEAVE},
@@ -8088,6 +8080,7 @@
  * Search a window for the current buffer.  Save the cursor position and
  * screen offset.
  * Set "curbuf" and "curwin" to match "buf".
+ * When FEAT_AUTOCMD is not defined another version is used, see below.
  */
     void
 aucmd_prepbuf(aco, buf)
@@ -8151,6 +8144,7 @@
 /*
  * Cleanup after executing autocommands for a (hidden) buffer.
  * Restore the window as it was (if possible).
+ * When FEAT_AUTOCMD is not defined another version is used, see below.
  */
     void
 aucmd_restbuf(aco)
@@ -8295,7 +8289,11 @@
 {
     int		state;
 
-    if (!did_cursorhold && has_cursorhold() && !Recording)
+    if (!did_cursorhold && has_cursorhold() && !Recording
+#ifdef FEAT_INS_EXPAND
+	    && !ins_compl_active()
+#endif
+	    )
     {
 	state = get_real_state();
 	if (state == NORMAL_BUSY || (state & INSERT) != 0)
@@ -9063,8 +9061,38 @@
     return retval;
 }
 
+#else	/* FEAT_AUTOCMD */
+
+/*
+ * Prepare for executing commands for (hidden) buffer "buf".
+ * This is the non-autocommand version, it simply saves "curbuf" and sets
+ * "curbuf" and "curwin" to match "buf".
+ */
+    void
+aucmd_prepbuf(aco, buf)
+    aco_save_T	*aco;		/* structure to save values in */
+    buf_T	*buf;		/* new curbuf */
+{
+    aco->save_buf = buf;
+    curbuf = buf;
+    curwin->w_buffer = buf;
+}
+
+/*
+ * Restore after executing commands for a (hidden) buffer.
+ * This is the non-autocommand version.
+ */
+    void
+aucmd_restbuf(aco)
+    aco_save_T	*aco;		/* structure holding saved values */
+{
+    curbuf = aco->save_buf;
+    curwin->w_buffer = curbuf;
+}
+
 #endif	/* FEAT_AUTOCMD */
 
+
 #if defined(FEAT_AUTOCMD) || defined(FEAT_WILDIGN) || defined(PROTO)
 /*
  * Try matching a filename with a "pattern" ("prog" is NULL), or use the
diff -Naur vim70.orig/src/fold.c vim70/src/fold.c
--- vim70.orig/src/fold.c	2006-04-22 12:35:56.000000000 -0700
+++ vim70/src/fold.c	2006-11-29 16:10:14.000000000 -0800
@@ -2971,7 +2971,11 @@
     else
 	flp->lvl = get_indent_buf(buf, lnum) / buf->b_p_sw;
     if (flp->lvl > flp->wp->w_p_fdn)
+    {
 	flp->lvl = flp->wp->w_p_fdn;
+	if (flp->lvl < 0)
+	    flp->lvl = 0;
+    }
 }
 
 /* foldlevelDiff() {{{2 */
diff -Naur vim70.orig/src/getchar.c vim70/src/getchar.c
--- vim70.orig/src/getchar.c	2006-05-03 10:29:21.000000000 -0700
+++ vim70/src/getchar.c	2006-11-29 16:10:08.000000000 -0800
@@ -1451,7 +1451,8 @@
 {
     updatescript(0);
 #ifdef FEAT_EVAL
-    garbage_collect();
+    if (may_garbage_collect)
+	garbage_collect();
 #endif
 }
 
@@ -1502,6 +1503,13 @@
     int		i;
 #endif
 
+#ifdef FEAT_EVAL
+    /* Do garbage collection when garbagecollect() was called previously and
+     * we are now at the toplevel. */
+    if (may_garbage_collect && want_garbage_collect)
+	garbage_collect();
+#endif
+
     /*
      * If a character was put back with vungetc, it was already processed.
      * Return it directly.
@@ -1511,13 +1519,13 @@
 	c = old_char;
 	old_char = -1;
 	mod_mask = old_mod_mask;
-	return c;
     }
-
-    mod_mask = 0x0;
-    last_recorded_len = 0;
-    for (;;)			/* this is done twice if there are modifiers */
+    else
     {
+      mod_mask = 0x0;
+      last_recorded_len = 0;
+      for (;;)			/* this is done twice if there are modifiers */
+      {
 	if (mod_mask)		/* no mapping after modifier has been read */
 	{
 	    ++no_mapping;
@@ -1695,8 +1703,20 @@
 	}
 #endif
 
-	return c;
+	break;
+      }
     }
+
+#ifdef FEAT_EVAL
+    /*
+     * In the main loop "may_garbage_collect" can be set to do garbage
+     * collection in the first next vgetc().  It's disabled after that to
+     * avoid internally used Lists and Dicts to be freed.
+     */
+    may_garbage_collect = FALSE;
+#endif
+
+    return c;
 }
 
 /*
@@ -1940,10 +1960,13 @@
 			c = Ctrl_C;
 		    flush_buffers(TRUE);	/* flush all typeahead */
 
-		    /* Also record this character, it might be needed to
-		     * get out of Insert mode. */
-		    *typebuf.tb_buf = c;
-		    gotchars(typebuf.tb_buf, 1);
+		    if (advance)
+		    {
+			/* Also record this character, it might be needed to
+			 * get out of Insert mode. */
+			*typebuf.tb_buf = c;
+			gotchars(typebuf.tb_buf, 1);
+		    }
 		    cmd_silent = FALSE;
 
 		    break;
diff -Naur vim70.orig/src/globals.h vim70/src/globals.h
--- vim70.orig/src/globals.h	2006-04-30 06:16:23.000000000 -0700
+++ vim70/src/globals.h	2006-11-29 16:10:10.000000000 -0800
@@ -166,6 +166,7 @@
 EXTERN int	emsg_off INIT(= 0);	    /* don't display errors for now,
 					       unless 'debug' is set. */
 EXTERN int	info_message INIT(= FALSE); /* printing informative message */
+EXTERN int      msg_hist_off INIT(= FALSE); /* don't add messages to history */
 #ifdef FEAT_EVAL
 EXTERN int	emsg_skip INIT(= 0);	    /* don't display errors for
 					       expression that is skipped */
@@ -300,9 +301,16 @@
 #endif
 
 #ifdef FEAT_EVAL
-EXTERN scid_T	current_SID INIT(= 0);	    /* ID of script being sourced or
-					       was sourced to define the
-					       current function. */
+/* Garbage collection can only take place when we are sure there are no Lists
+ * or Dictionaries being used internally.  This is flagged with
+ * "may_garbage_collect" when we are at the toplevel.
+ * "want_garbage_collect" is set by the garbagecollect() function, which means
+ * we do garbage collection before waiting for a char at the toplevel. */
+EXTERN int	may_garbage_collect INIT(= FALSE);
+EXTERN int	want_garbage_collect INIT(= FALSE);
+
+/* ID of script being sourced or was sourced to define the current function. */
+EXTERN scid_T	current_SID INIT(= 0);
 #endif
 
 #if defined(FEAT_EVAL) || defined(FEAT_SYN_HL)
@@ -1441,7 +1449,7 @@
 EXTERN char_u e_readonly[]	INIT(= N_("E45: 'readonly' option is set (add ! to override)"));
 #ifdef FEAT_EVAL
 EXTERN char_u e_readonlyvar[]	INIT(= N_("E46: Cannot change read-only variable \"%s\""));
-EXTERN char_u e_readonlysbx[]	INIT(= N_("E46: Cannot set variable in the sandbox: \"%s\""));
+EXTERN char_u e_readonlysbx[]	INIT(= N_("E794: Cannot set variable in the sandbox: \"%s\""));
 #endif
 #ifdef FEAT_QUICKFIX
 EXTERN char_u e_readerrf[]	INIT(= N_("E47: Error while reading errorfile"));
diff -Naur vim70.orig/src/gui_at_fs.c vim70/src/gui_at_fs.c
--- vim70.orig/src/gui_at_fs.c	2005-07-09 04:30:17.000000000 -0700
+++ vim70/src/gui_at_fs.c	2006-11-29 16:09:50.000000000 -0800
@@ -1861,27 +1861,27 @@
     XtPointer	pnew;
 {
     SFDir	*dir;
-    int		nw;
+    int		nw = (int)(long)pnew;
 
     dir = &(SFdirs[SFdirPtr + (int)(long)n]);
 
 #ifdef FEAT_GUI_NEXTAW
-    if ((int)(long)pnew < 0)
+    if (nw < 0)
     {
-	if ((int)(long)pnew > -SFvScrollHeight)
-	    (int)(long)pnew = -1;
+	if (nw > -SFvScrollHeight)
+	    nw = -1;
 	else
-	    (int)(long)pnew = -SFlistSize;
+	    nw = -SFlistSize;
     }
-    else if ((int)(long)pnew > 0)
+    else if (nw > 0)
     {
-	if ((int)(long)pnew < SFvScrollHeight)
-	    (int)(long)pnew = 1;
+	if (nw < SFvScrollHeight)
+	    nw = 1;
 	else
-	    (int)(long)pnew = SFlistSize;
+	    nw = SFlistSize;
     }
 #endif
-    nw = dir->vOrigin + (int)(long)pnew;
+    nw += dir->vOrigin;
 
     if (nw > dir->nEntries - SFlistSize)
 	nw = dir->nEntries - SFlistSize;
@@ -1941,27 +1941,27 @@
     XtPointer	pnew;
 {
     SFDir	*dir;
-    int		nw;
+    int		nw = (int)(long)pnew;
 
     dir = &(SFdirs[SFdirPtr + (int)(long)n]);
 
 #ifdef FEAT_GUI_NEXTAW
-    if ((int)(long)pnew < 0)
+    if (nw < 0)
     {
-	if ((int)(long)pnew > -SFhScrollWidth)
-	    (int)(long)pnew = -1;
+	if (nw > -SFhScrollWidth)
+	    nw = -1;
 	else
-	    (int)(long)pnew = -SFcharsPerEntry;
+	    nw = -SFcharsPerEntry;
     }
-    else if ((int)(long)pnew > 0)
+    else if (nw > 0)
     {
-	if ((int)(long)pnew < SFhScrollWidth)
-	    (int)(long)pnew = 1;
+	if (nw < SFhScrollWidth)
+	    nw = 1;
 	else
-	    (int)(long)pnew = SFcharsPerEntry;
+	    nw = SFcharsPerEntry;
     }
 #endif
-    nw = dir->hOrigin + (int)(long)pnew;
+    nw += dir->hOrigin;
 
     if (nw > dir->nChars - SFcharsPerEntry)
 	nw = dir->nChars - SFcharsPerEntry;
@@ -2038,26 +2038,26 @@
     XtPointer	client_data;
     XtPointer	pnew;
 {
-    int		nw;
+    int		nw = (int)(long)pnew;
     float	f;
 
 #ifdef FEAT_GUI_NEXTAW
-    if ((int)(long)pnew < 0)
+    if (nw < 0)
     {
-	if ((int)(long)pnew > -SFpathScrollWidth)
-	    (int)(long)pnew = -1;
+	if (nw > -SFpathScrollWidth)
+	    nw = -1;
 	else
-	    (int)(long)pnew = -3;
+	    nw = -3;
     }
-    else if ((int)(long)pnew > 0)
+    else if (nw > 0)
     {
-	if ((int)(long)pnew < SFpathScrollWidth)
-	    (int)(long)pnew = 1;
+	if (nw < SFpathScrollWidth)
+	    nw = 1;
 	else
-	    (int)(long)pnew = 3;
+	    nw = 3;
     }
 #endif
-    nw = SFdirPtr + (int)(long)pnew;
+    nw += SFdirPtr;
 
     if (nw > SFdirEnd - 3)
 	nw = SFdirEnd - 3;
diff -Naur vim70.orig/src/gui_beval.c vim70/src/gui_beval.c
--- vim70.orig/src/gui_beval.c	2006-05-04 12:29:51.000000000 -0700
+++ vim70/src/gui_beval.c	2006-11-29 16:09:58.000000000 -0800
@@ -926,7 +926,7 @@
 #  define IS_NONPRINTABLE(c) (((c) < 0x20 && (c) != TAB && (c) != NL) \
 			      || (c) == DEL)
     static void
-set_printable_label_text(GtkLabel *label, char_u *msg)
+set_printable_label_text(GtkLabel *label, char_u *text)
 {
     char_u	    *convbuf = NULL;
     char_u	    *buf;
@@ -940,14 +940,14 @@
     /* Convert to UTF-8 if it isn't already */
     if (output_conv.vc_type != CONV_NONE)
     {
-	convbuf = string_convert(&output_conv, msg, NULL);
+	convbuf = string_convert(&output_conv, text, NULL);
 	if (convbuf != NULL)
-	    msg = convbuf;
+	    text = convbuf;
     }
 
     /* First let's see how much we need to allocate */
     len = 0;
-    for (p = msg; *p != NUL; p += charlen)
+    for (p = text; *p != NUL; p += charlen)
     {
 	if ((*p & 0x80) == 0)	/* be quick for ASCII */
 	{
@@ -992,7 +992,7 @@
 				     (unsigned long)pixel, &color);
 
 	pdest = buf;
-	p = msg;
+	p = text;
 	while (*p != NUL)
 	{
 	    /* Be quick for ASCII */
diff -Naur vim70.orig/src/gui.c vim70/src/gui.c
--- vim70.orig/src/gui.c	2006-05-03 04:00:59.000000000 -0700
+++ vim70/src/gui.c	2006-11-29 16:10:10.000000000 -0800
@@ -187,9 +187,10 @@
 #endif
 
 #ifdef FEAT_AUTOCMD
-    /* If the GUI started successfully, trigger the GUIEnter event */
-    if (gui.in_use)
-	apply_autocmds(EVENT_GUIENTER, NULL, NULL, FALSE, curbuf);
+    /* If the GUI started successfully, trigger the GUIEnter event, otherwise
+     * the GUIFailed event. */
+    apply_autocmds(gui.in_use ? EVENT_GUIENTER : EVENT_GUIFAILED,
+						   NULL, NULL, FALSE, curbuf);
 #endif
 
     --recursive;
@@ -636,6 +637,7 @@
 
 #if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_X11) || defined(FEAT_GUI_MSWIN) \
 	|| defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC) || defined(PROTO)
+# define NEED_GUI_UPDATE_SCREEN 1
 /*
  * Called when the GUI shell is closed by the user.  If there are no changed
  * files Vim exits, otherwise there will be a dialog to ask the user what to
@@ -664,8 +666,7 @@
 
     exiting = FALSE;
     cmdmod = save_cmdmod;
-    setcursor();		/* position cursor */
-    out_flush();
+    gui_update_screen();	/* redraw, window may show changed buffer */
 }
 #endif
 
@@ -2872,6 +2873,9 @@
      */
     if ((State == NORMAL || State == NORMAL_BUSY || (State & INSERT))
 	    && Y_2_ROW(y) >= topframe->fr_height
+# ifdef FEAT_WINDOWS
+						+ firstwin->w_winrow
+# endif
 	    && button != MOUSE_DRAG
 # ifdef FEAT_MOUSESHAPE
 	    && !drag_status_line
@@ -3733,6 +3737,12 @@
     if (dont_scroll || input_available())
 	return;
 #endif
+#ifdef FEAT_INS_EXPAND
+    /* Disallow scrolling the current window when the completion popup menu is
+     * visible. */
+    if ((sb->wp == NULL || sb->wp == curwin) && pum_visible())
+	return;
+#endif
 
 #ifdef FEAT_RIGHTLEFT
     if (sb->wp == NULL && curwin->w_p_rl)
@@ -4207,6 +4217,12 @@
 	updateWindow(wp);   /* update window, status line, and cmdline */
     }
 
+#ifdef FEAT_INS_EXPAND
+    /* May need to redraw the popup menu. */
+    if (pum_visible())
+	pum_redraw();
+#endif
+
     return (wp == curwin && !equalpos(curwin->w_cursor, old_cursor));
 }
 
@@ -4515,7 +4531,7 @@
     int		y;
 {
     win_T	*wp;
-    char_u	st[6];
+    char_u	st[8];
 
     /* Ignore this while still starting up. */
     if (!gui.in_use || gui.starting)
@@ -4603,11 +4619,11 @@
     /* Don't move the mouse when it's left or right of the Vim window */
     if (x < 0 || x > Columns * gui.char_width)
 	return;
+    if (y >= 0
 # ifdef FEAT_WINDOWS
-    if (Y_2_ROW(y) >= tabline_height())
-# else
-    if (y >= 0)
+	    && Y_2_ROW(y) >= tabline_height()
 # endif
+       )
 	wp = xy2win(x, y);
     if (wp != curwin && wp != NULL)	/* If in other than current window */
     {
@@ -4807,6 +4823,7 @@
 #endif
 
 #if defined(FIND_REPLACE_DIALOG) || defined(FEAT_SUN_WORKSHOP) \
+	|| defined(NEED_GUI_UPDATE_SCREEN) \
 	|| defined(PROTO)
 /*
  * Update the current window and the screen.
diff -Naur vim70.orig/src/gui_gtk.c vim70/src/gui_gtk.c
--- vim70.orig/src/gui_gtk.c	2006-05-05 04:52:52.000000000 -0700
+++ vim70/src/gui_gtk.c	2006-11-29 16:10:13.000000000 -0800
@@ -957,15 +957,15 @@
 get_menu_position(vimmenu_T *menu)
 {
     vimmenu_T	*node;
-    int		index = 0;
+    int		idx = 0;
 
     for (node = menu->parent->children; node != menu; node = node->next)
     {
 	g_return_val_if_fail(node != NULL, -1);
-	++index;
+	++idx;
     }
 
-    return index;
+    return idx;
 }
 #endif /* FEAT_TOOLBAR && HAVE_GTK2 */
 
@@ -1275,18 +1275,13 @@
     title = CONVERT_TO_UTF8(title);
 # endif
 
-    /* Concatenate "initdir" and "dflt". */
+    /* GTK has a bug, it only works with an absolute path. */
     if (initdir == NULL || *initdir == NUL)
 	mch_dirname(dirbuf, MAXPATHL);
-    else if (STRLEN(initdir) + 2 < MAXPATHL)
-	STRCPY(dirbuf, initdir);
-    else
+    else if (vim_FullName(initdir, dirbuf, MAXPATHL - 2, FALSE) == FAIL)
 	dirbuf[0] = NUL;
     /* Always need a trailing slash for a directory. */
     add_pathsep(dirbuf);
-    if (dflt != NULL && *dflt != NUL
-			      && STRLEN(dirbuf) + 2 + STRLEN(dflt) < MAXPATHL)
-	STRCAT(dirbuf, dflt);
 
     /* If our pointer is currently hidden, then we should show it. */
     gui_mch_mousehide(FALSE);
@@ -1298,8 +1293,8 @@
 	    GTK_WINDOW(gui.mainwin),
 	    saving ? GTK_FILE_CHOOSER_ACTION_SAVE
 					   : GTK_FILE_CHOOSER_ACTION_OPEN,
-	    saving ? GTK_STOCK_SAVE : GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
 	    GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+	    saving ? GTK_STOCK_SAVE : GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
 	    NULL);
     gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fc),
 						       (const gchar *)dirbuf);
@@ -1341,6 +1336,11 @@
     else
 	gtk_window_set_title(GTK_WINDOW(gui.filedlg), (const gchar *)title);
 
+    /* Concatenate "initdir" and "dflt". */
+    if (dflt != NULL && *dflt != NUL
+			      && STRLEN(dirbuf) + 2 + STRLEN(dflt) < MAXPATHL)
+	STRCAT(dirbuf, dflt);
+
     gtk_file_selection_set_filename(GTK_FILE_SELECTION(gui.filedlg),
 						      (const gchar *)dirbuf);
 # ifndef HAVE_GTK2
@@ -2127,7 +2127,7 @@
     char    **ync;  /* "yes no cancel" */
     char    **buttons;
     int	    n_buttons = 0;
-    int	    index;
+    int	    idx;
 
     button_string = vim_strsave(button_string); /* must be writable */
     if (button_string == NULL)
@@ -2161,12 +2161,12 @@
      * Well, apparently somebody changed his mind: with GTK 2.2.4 it works the
      * other way around...
      */
-    for (index = 1; index <= n_buttons; ++index)
+    for (idx = 1; idx <= n_buttons; ++idx)
     {
 	char	*label;
 	char_u	*label8;
 
-	label = buttons[index - 1];
+	label = buttons[idx - 1];
 	/*
 	 * Perform some guesswork to find appropriate stock items for the
 	 * buttons.  We have to compare with a sample of the translated
@@ -2188,7 +2188,7 @@
 	    else if (button_equal(label, "Cancel")) label = GTK_STOCK_CANCEL;
 	}
 	label8 = CONVERT_TO_UTF8((char_u *)label);
-	gtk_dialog_add_button(dialog, (const gchar *)label8, index);
+	gtk_dialog_add_button(dialog, (const gchar *)label8, idx);
 	CONVERT_TO_UTF8_FREE(label8);
     }
 
diff -Naur vim70.orig/src/gui_gtk_x11.c vim70/src/gui_gtk_x11.c
--- vim70.orig/src/gui_gtk_x11.c	2006-05-04 23:58:59.000000000 -0700
+++ vim70/src/gui_gtk_x11.c	2006-11-29 16:09:58.000000000 -0800
@@ -3233,12 +3233,12 @@
 on_select_tab(
 	GtkNotebook	*notebook,
 	GtkNotebookPage *page,
-	gint		index,
+	gint		idx,
 	gpointer	data)
 {
     if (!ignore_tabline_evt)
     {
-	if (send_tabline_event(index + 1) && gtk_main_level() > 0)
+	if (send_tabline_event(idx + 1) && gtk_main_level() > 0)
 	    gtk_main_quit();
     }
 }
@@ -5303,13 +5303,13 @@
 # ifdef HAVE_GTK2
     if (font != NOFONT)
     {
-	char	*name = pango_font_description_to_string(font);
+	char	*pangoname = pango_font_description_to_string(font);
 
-	if (name != NULL)
+	if (pangoname != NULL)
 	{
-	    char_u	*s = vim_strsave((char_u *)name);
+	    char_u	*s = vim_strsave((char_u *)pangoname);
 
-	    g_free(name);
+	    g_free(pangoname);
 	    return s;
 	}
     }
@@ -6241,24 +6241,20 @@
 {
     GdkGCValues values;
     GdkGC *invert_gc;
-    GdkColor foreground;
-    GdkColor background;
 
     if (gui.drawarea->window == NULL)
 	return;
 
-    foreground.pixel = gui.norm_pixel ^ gui.back_pixel;
-    background.pixel = gui.norm_pixel ^ gui.back_pixel;
-
-    values.foreground = foreground;
-    values.background = background;
+    values.foreground.pixel = gui.norm_pixel ^ gui.back_pixel;
+    values.background.pixel = gui.norm_pixel ^ gui.back_pixel;
     values.function = GDK_XOR;
     invert_gc = gdk_gc_new_with_values(gui.drawarea->window,
 				       &values,
 				       GDK_GC_FOREGROUND |
 				       GDK_GC_BACKGROUND |
 				       GDK_GC_FUNCTION);
-    gdk_gc_set_exposures(invert_gc, gui.visibility != GDK_VISIBILITY_UNOBSCURED);
+    gdk_gc_set_exposures(invert_gc, gui.visibility !=
+						   GDK_VISIBILITY_UNOBSCURED);
     gdk_draw_rectangle(gui.drawarea->window, invert_gc,
 		       TRUE,
 		       FILL_X(c), FILL_Y(r),
diff -Naur vim70.orig/src/gui_xmebw.c vim70/src/gui_xmebw.c
--- vim70.orig/src/gui_xmebw.c	2006-04-30 08:32:32.000000000 -0700
+++ vim70/src/gui_xmebw.c	2006-11-29 16:10:13.000000000 -0800
@@ -47,13 +47,13 @@
 #include "gui_xmebwp.h"
 
 /* Provide some missing wrappers, which are missed from the LessTif
- * implementation.
+ * implementation.  Also missing in Motif 1.2 and earlier.
  *
  * We neither use XmeGetPixmapData or _XmGetPixmapData, since with LessTif the
  * pixmap will not appear in it's caches properly. We cache the interresting
  * values in XmEnhancedButtonPart instead ourself.
  */
-#ifdef LESSTIF_VERSION
+#if defined(LESSTIF_VERSION) || (XmVersion <= 1002)
 # ifndef Lab_IsMenupane
 #  define Lab_IsMenupane(w) (Lab_MenuType(w) == (int)XmMENU_POPUP || \
 		    Lab_MenuType(w) == (int)XmMENU_PULLDOWN)
@@ -138,6 +138,19 @@
     }
 };
 
+/* This is needed to work around a bug in Lesstif 2, leaving the extension
+ * NULL somehow results in getting it set to an invalid pointer. */
+XmPrimitiveClassExtRec xmEnhancedButtonPrimClassExtRec =
+{
+    /* next_extension      */ NULL,
+    /* record_type         */ NULLQUARK,
+    /* version             */ XmPrimitiveClassExtVersion,
+    /* record_size         */ sizeof(XmPrimitiveClassExtRec),
+    /* widget_baseline     */ XmInheritBaselineProc,
+    /* widget_display_rect */ XmInheritDisplayRectProc,
+    /* widget_margins      */ NULL
+};
+
 XmEnhancedButtonClassRec xmEnhancedButtonClassRec =
 {
     {
@@ -184,7 +197,7 @@
 	/* arm and activate	 */ XmInheritArmAndActivate,
 	/* synthetic resources	 */ NULL,
 	/* number of syn res	 */ 0,
-	/* extension		 */ NULL,
+	/* extension		 */ (XtPointer)&xmEnhancedButtonPrimClassExtRec,
     },
 
     /* label_class fields */
@@ -480,7 +493,7 @@
 	    || (eb->core.height <= 2 * eb->primitive.highlight_thickness))
 	return;
 
-#ifndef LESSTIF_VERSION
+#if !defined(LESSTIF_VERSION) && (XmVersion > 1002)
     {
 	XmDisplay	dpy;
 
@@ -641,7 +654,7 @@
     GC		tmp_gc = NULL;
     Boolean	replaceGC = False;
     Boolean	deadjusted = False;
-#ifndef LESSTIF_VERSION
+#if !defined(LESSTIF_VERSION) && (XmVersion > 1002)
     XmDisplay	dpy = (XmDisplay)XmGetXmDisplay(XtDisplay(eb));
     Boolean	etched_in = dpy->display.enable_etched_in_menu;
 #else
@@ -726,7 +739,7 @@
 	if ((((ShellWidget) XtParent(XtParent(eb)))->shell.popped_up)
 		&& _XmGetInDragMode((Widget) eb))
 	{
-#ifndef LESSTIF_VERSION
+#if !defined(LESSTIF_VERSION) && (XmVersion > 1002)
 	    XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(wid));
 	    Boolean etched_in = dpy->display.enable_etched_in_menu;
 #else
@@ -810,7 +823,7 @@
 
     if (Lab_IsMenupane(eb))
     {
-#ifndef LESSTIF_VERSION
+#if !defined(LESSTIF_VERSION) && (XmVersion > 1002)
 	XmDisplay dpy = (XmDisplay) XmGetXmDisplay(XtDisplay(wid));
 	Boolean etched_in = dpy->display.enable_etched_in_menu;
 #else
@@ -1150,7 +1163,7 @@
 Redisplay(Widget w, XEvent *event, Region region)
 {
     XmEnhancedButtonWidget  eb = (XmEnhancedButtonWidget) w;
-#ifndef LESSTIF_VERSION
+#if !defined(LESSTIF_VERSION) && (XmVersion > 1002)
     XmDisplay		    dpy;
     XtEnum		    default_button_emphasis;
 #endif
@@ -1162,7 +1175,7 @@
     if (!XtIsRealized((Widget)eb))
 	return;
 
-#ifndef LESSTIF_VERSION
+#if !defined(LESSTIF_VERSION) && (XmVersion > 1002)
     dpy = (XmDisplay)XmGetXmDisplay(XtDisplay(eb));
     default_button_emphasis = dpy->display.default_button_emphasis;
 #endif
@@ -1241,7 +1254,7 @@
     {
 	int adjust = 0;
 
-#ifndef LESSTIF_VERSION
+#if !defined(LESSTIF_VERSION) && (XmVersion > 1002)
 	/*
 	 *  NOTE: PushButton has two types of shadows: primitive-shadow and
 	 *  default-button-shadow.  If pushbutton is in a menu only primitive
@@ -1289,7 +1302,7 @@
 			  adjust, adjust, rectwidth, rectheight, borderwidth);
 	    }
 
-#ifndef LESSTIF_VERSION
+#if !defined(LESSTIF_VERSION) && (XmVersion > 1002)
 	    switch (default_button_emphasis)
 	    {
 		case XmINTERNAL_HIGHLIGHT:
@@ -1365,7 +1378,7 @@
 		    default_button_shadow_thickness =
 			       eb->pushbutton.default_button_shadow_thickness;
 
-#ifndef LESSTIF_VERSION
+#if !defined(LESSTIF_VERSION) && (XmVersion > 1002)
 		/*
 		 * Compute location of bounding box to contain the
 		 * defaultButtonShadow.
diff -Naur vim70.orig/src/hardcopy.c vim70/src/hardcopy.c
--- vim70.orig/src/hardcopy.c	2006-05-04 03:09:58.000000000 -0700
+++ vim70/src/hardcopy.c	2006-11-29 16:09:58.000000000 -0800
@@ -1794,29 +1794,27 @@
     static int
 prt_resfile_next_line()
 {
-    int     index;
+    int     idx;
 
     /* Move to start of next line and then find end of line */
-    index = prt_resfile.line_end + 1;
-    while (index < prt_resfile.len)
+    idx = prt_resfile.line_end + 1;
+    while (idx < prt_resfile.len)
     {
-	if (prt_resfile.buffer[index] != PSLF && prt_resfile.buffer[index]
-									!= PSCR)
+	if (prt_resfile.buffer[idx] != PSLF && prt_resfile.buffer[idx] != PSCR)
 	    break;
-	index++;
+	idx++;
     }
-    prt_resfile.line_start = index;
+    prt_resfile.line_start = idx;
 
-    while (index < prt_resfile.len)
+    while (idx < prt_resfile.len)
     {
-	if (prt_resfile.buffer[index] == PSLF || prt_resfile.buffer[index]
-									== PSCR)
+	if (prt_resfile.buffer[idx] == PSLF || prt_resfile.buffer[idx] == PSCR)
 	    break;
-	index++;
+	idx++;
     }
-    prt_resfile.line_end = index;
+    prt_resfile.line_end = idx;
 
-    return (index < prt_resfile.len);
+    return (idx < prt_resfile.len);
 }
 
     static int
@@ -1837,14 +1835,14 @@
 prt_resfile_skip_nonws(offset)
     int     offset;
 {
-    int     index;
+    int     idx;
 
-    index = prt_resfile.line_start + offset;
-    while (index < prt_resfile.line_end)
+    idx = prt_resfile.line_start + offset;
+    while (idx < prt_resfile.line_end)
     {
-	if (isspace(prt_resfile.buffer[index]))
-	    return index - prt_resfile.line_start;
-	index++;
+	if (isspace(prt_resfile.buffer[idx]))
+	    return idx - prt_resfile.line_start;
+	idx++;
     }
     return -1;
 }
@@ -1853,14 +1851,14 @@
 prt_resfile_skip_ws(offset)
     int     offset;
 {
-    int     index;
+    int     idx;
 
-    index = prt_resfile.line_start + offset;
-    while (index < prt_resfile.line_end)
+    idx = prt_resfile.line_start + offset;
+    while (idx < prt_resfile.line_end)
     {
-	if (!isspace(prt_resfile.buffer[index]))
-	    return index - prt_resfile.line_start;
-	index++;
+	if (!isspace(prt_resfile.buffer[idx]))
+	    return idx - prt_resfile.line_start;
+	idx++;
     }
     return -1;
 }
@@ -2478,7 +2476,7 @@
     char_u	*p_encoding;
     struct prt_ps_encoding_S *p_mbenc;
     struct prt_ps_encoding_S *p_mbenc_first;
-    struct prt_ps_charset_S  *p_mbchar;
+    struct prt_ps_charset_S  *p_mbchar = NULL;
 #endif
 
 #if 0
@@ -2516,7 +2514,6 @@
     if (!(props & ENC_8BIT) && ((*p_pmcs != NUL) || !(props & ENC_UNICODE)))
     {
 	p_mbenc_first = NULL;
-	p_mbchar = NULL;
 	for (cmap = 0; cmap < NUM_ELEMENTS(prt_ps_mbfonts); cmap++)
 	    if (prt_match_encoding((char *)p_encoding, &prt_ps_mbfonts[cmap],
 								    &p_mbenc))
diff -Naur vim70.orig/src/if_cscope.c vim70/src/if_cscope.c
--- vim70.orig/src/if_cscope.c	2006-04-18 01:54:15.000000000 -0700
+++ vim70/src/if_cscope.c	2006-11-29 16:10:15.000000000 -0800
@@ -989,8 +989,7 @@
 {
     int i;
     char *cmd;
-    char **matches, **contexts;
-    int nummatches[CSCOPE_MAX_CONNECTIONS], totmatches, matched;
+    int nummatches[CSCOPE_MAX_CONNECTIONS], totmatches;
 #ifdef FEAT_QUICKFIX
     char cmdletter;
     char *qfpos;
@@ -1009,7 +1008,7 @@
     totmatches = 0;
     for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
     {
-	if (csinfo[i].fname == NULL)
+	if (csinfo[i].fname == NULL || csinfo[i].to_fp == NULL)
 	    continue;
 
 	/* send cmd to cscope */
@@ -1101,38 +1100,44 @@
     if (qfpos != NULL && *qfpos != '0' && totmatches > 0)
     {
 	/* fill error list */
-	FILE *f;
-	char_u *tmp = vim_tempname('c');
+	FILE	    *f;
+	char_u	    *tmp = vim_tempname('c');
 	qf_info_T   *qi = NULL;
 	win_T	    *wp = NULL;
 
 	f = mch_fopen((char *)tmp, "w");
-	cs_file_results(f, nummatches);
-	fclose(f);
-	if (use_ll)	    /* Use location list */
-	    wp = curwin;
-	/* '-' starts a new error list */
-	if (qf_init(wp, tmp, (char_u *)"%f%*\\t%l%*\\t%m", *qfpos == '-') > 0)
+	if (f == NULL)
+	    EMSG2(_(e_notopen), tmp);
+	else
 	{
-# ifdef FEAT_WINDOWS
-	    if (postponed_split != 0)
+	    cs_file_results(f, nummatches);
+	    fclose(f);
+	    if (use_ll)	    /* Use location list */
+		wp = curwin;
+	    /* '-' starts a new error list */
+	    if (qf_init(wp, tmp, (char_u *)"%f%*\\t%l%*\\t%m",
+							   *qfpos == '-') > 0)
 	    {
-		win_split(postponed_split > 0 ? postponed_split : 0,
+# ifdef FEAT_WINDOWS
+		if (postponed_split != 0)
+		{
+		    win_split(postponed_split > 0 ? postponed_split : 0,
 						       postponed_split_flags);
 #  ifdef FEAT_SCROLLBIND
-		curwin->w_p_scb = FALSE;
+		    curwin->w_p_scb = FALSE;
 #  endif
-		postponed_split = 0;
-	    }
+		    postponed_split = 0;
+		}
 # endif
-	    if (use_ll)
-		/*
-		 * In the location list window, use the displayed location
-		 * list. Otherwise, use the location list for the window.
-		 */
-		qi = (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL) ?
-				    wp->w_llist_ref : wp->w_llist;
-	    qf_jump(qi, 0, 0, forceit);
+		if (use_ll)
+		    /*
+		     * In the location list window, use the displayed location
+		     * list. Otherwise, use the location list for the window.
+		     */
+		    qi = (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL)
+			?  wp->w_llist_ref : wp->w_llist;
+		qf_jump(qi, 0, 0, forceit);
+	    }
 	}
 	mch_remove(tmp);
 	vim_free(tmp);
@@ -1141,6 +1146,9 @@
     else
 #endif /* FEAT_QUICKFIX */
     {
+	char **matches = NULL, **contexts = NULL;
+	int matched = 0;
+
 	/* read output */
 	cs_fill_results((char *)pat, totmatches, nummatches, &matches,
 							 &contexts, &matched);
@@ -1721,7 +1729,7 @@
 	       continue;
 
 	   context = (char *)alloc((unsigned)strlen(cntx)+5);
-	   if (context==NULL)
+	   if (context == NULL)
 	       continue;
 
 	   if (strcmp(cntx, "<global>")==0)
@@ -1729,7 +1737,7 @@
 	   else
 	       sprintf(context, "<<%s>>", cntx);
 
-	   if (search==NULL)
+	   if (search == NULL)
 	       fprintf(f, "%s\t%s\t%s\n", fullname, slno, context);
 	   else
 	       fprintf(f, "%s\t%s\t%s %s\n", fullname, slno, context, search);
diff -Naur vim70.orig/src/if_perl.xs vim70/src/if_perl.xs
--- vim70.orig/src/if_perl.xs	2006-03-06 10:57:16.000000000 -0800
+++ vim70/src/if_perl.xs	2006-11-29 16:09:56.000000000 -0800
@@ -155,8 +155,8 @@
 static int (*perl_run)(PerlInterpreter*);
 static int (*perl_parse)(PerlInterpreter*, XSINIT_t, int, char**, char**);
 static void* (*Perl_get_context)(void);
-static void (*Perl_croak)(pTHX_ const char*, ...) __attribute__((noreturn));
-static void (*Perl_croak_nocontext)(const char*, ...) __attribute__((noreturn));
+static void (*Perl_croak)(pTHX_ const char*, ...);
+static void (*Perl_croak_nocontext)(const char*, ...);
 static I32 (*Perl_dowantarray)(pTHX);
 static void (*Perl_free_tmps)(pTHX);
 static HV* (*Perl_gv_stashpv)(pTHX_ const char*, I32);
@@ -1056,7 +1056,6 @@
     int i;
     long lnum;
     char *line;
-    buf_T *savebuf;
     PPCODE:
     if (buf_valid(vimbuf))
     {
@@ -1069,14 +1068,20 @@
 	    line = SvPV(ST(i),PL_na);
 	    if (lnum > 0 && lnum <= vimbuf->b_ml.ml_line_count && line != NULL)
 	    {
-		savebuf = curbuf;
-		curbuf = vimbuf;
+		aco_save_T	aco;
+
+		/* set curwin/curbuf for "vimbuf" and save some things */
+		aucmd_prepbuf(&aco, vimbuf);
+
 		if (u_savesub(lnum) == OK)
 		{
 		    ml_replace(lnum, (char_u *)line, TRUE);
 		    changed_bytes(lnum, 0);
 		}
-		curbuf = savebuf;
+
+		/* restore curwin/curbuf and a few other things */
+		aucmd_restbuf(&aco);
+		/* Careful: autocommands may have made "vimbuf" invalid! */
 	    }
 	}
     }
@@ -1087,7 +1092,6 @@
 
     PREINIT:
     long i, lnum = 0, count = 0;
-    buf_T *savebuf;
     PPCODE:
     if (buf_valid(vimbuf))
     {
@@ -1114,16 +1118,23 @@
 	    {
 		if (lnum > 0 && lnum <= vimbuf->b_ml.ml_line_count)
 		{
-		    savebuf = curbuf;
-		    curbuf = vimbuf;
+		    aco_save_T	aco;
+
+		    /* set curwin/curbuf for "vimbuf" and save some things */
+		    aucmd_prepbuf(&aco, vimbuf);
+
 		    if (u_savedel(lnum, 1) == OK)
 		    {
 			ml_delete(lnum, 0);
 			deleted_lines_mark(lnum, 1L);
-			if (savebuf == curbuf)
+			if (aco.save_buf == curbuf)
 			    check_cursor();
 		    }
-		    curbuf = savebuf;
+
+		    /* restore curwin/curbuf and a few other things */
+		    aucmd_restbuf(&aco);
+		    /* Careful: autocommands may have made "vimbuf" invalid! */
+
 		    update_curbuf(VALID);
 		}
 	    }
@@ -1138,7 +1149,6 @@
     int		i;
     long	lnum;
     char	*line;
-    buf_T	*savebuf;
     PPCODE:
     if (buf_valid(vimbuf))
     {
@@ -1151,14 +1161,21 @@
 	    line = SvPV(ST(i),PL_na);
 	    if (lnum >= 0 && lnum <= vimbuf->b_ml.ml_line_count && line != NULL)
 	    {
-		savebuf = curbuf;
-		curbuf = vimbuf;
+		aco_save_T	aco;
+
+		/* set curwin/curbuf for "vimbuf" and save some things */
+		aucmd_prepbuf(&aco, vimbuf);
+
 		if (u_inssub(lnum + 1) == OK)
 		{
 		    ml_append(lnum, (char_u *)line, (colnr_T)0, FALSE);
 		    appended_lines_mark(lnum, 1L);
 		}
-		curbuf = savebuf;
+
+		/* restore curwin/curbuf and a few other things */
+		aucmd_restbuf(&aco);
+		/* Careful: autocommands may have made "vimbuf" invalid! */
+
 		update_curbuf(VALID);
 	    }
 	}
diff -Naur vim70.orig/src/if_python.c vim70/src/if_python.c
--- vim70.orig/src/if_python.c	2006-04-30 08:31:36.000000000 -0700
+++ vim70/src/if_python.c	2006-11-29 16:10:08.000000000 -0800
@@ -1463,7 +1463,7 @@
     if (this->buf && this->buf != INVALID_BUFFER_VALUE)
 	this->buf->b_python_ref = NULL;
 
-    PyMem_DEL(self);
+    Py_DECREF(self);
 }
 
     static PyObject *
@@ -1674,7 +1674,7 @@
     bufr = (BufferObject *)BufferNew(buf);
     if (bufr == NULL)
     {
-	PyMem_DEL(self);
+	Py_DECREF(self);
 	return NULL;
     }
     Py_INCREF(bufr);
@@ -1690,7 +1690,7 @@
 RangeDestructor(PyObject *self)
 {
     Py_DECREF(((RangeObject *)(self))->buf);
-    PyMem_DEL(self);
+    Py_DECREF(self);
 }
 
     static PyObject *
@@ -1944,7 +1944,7 @@
     if (this->win && this->win != INVALID_WINDOW_VALUE)
 	this->win->w_python_ref = NULL;
 
-    PyMem_DEL(self);
+    Py_DECREF(self);
 }
 
     static int
diff -Naur vim70.orig/src/if_ruby.c vim70/src/if_ruby.c
--- vim70.orig/src/if_ruby.c	2006-04-30 08:37:52.000000000 -0700
+++ vim70/src/if_ruby.c	2006-11-29 16:09:56.000000000 -0800
@@ -643,11 +643,14 @@
 
 static VALUE set_buffer_line(buf_T *buf, linenr_T n, VALUE str)
 {
-    buf_T *savebuf = curbuf;
-    char *line = STR2CSTR(str);
+    char	*line = STR2CSTR(str);
+    aco_save_T	aco;
+
+    if (n > 0 && n <= buf->b_ml.ml_line_count && line != NULL)
+    {
+	/* set curwin/curbuf for "buf" and save some things */
+	aucmd_prepbuf(&aco, buf);
 
-    if (n > 0 && n <= buf->b_ml.ml_line_count && line != NULL) {
-	curbuf = buf;
 	if (u_savesub(n) == OK) {
 	    ml_replace(n, (char_u *)line, TRUE);
 	    changed();
@@ -655,10 +658,15 @@
 	    syn_changed(n); /* recompute syntax hl. for this line */
 #endif
 	}
-	curbuf = savebuf;
+
+	/* restore curwin/curbuf and a few other things */
+	aucmd_restbuf(&aco);
+	/* Careful: autocommands may have made "buf" invalid! */
+
 	update_curbuf(NOT_VALID);
     }
-    else {
+    else
+    {
 	rb_raise(rb_eIndexError, "index %d out of buffer", n);
 	return Qnil; /* For stop warning */
     }
@@ -676,12 +684,15 @@
 
 static VALUE buffer_delete(VALUE self, VALUE num)
 {
-    buf_T *buf = get_buf(self);
-    buf_T *savebuf = curbuf;
-    long n = NUM2LONG(num);
+    buf_T	*buf = get_buf(self);
+    long	n = NUM2LONG(num);
+    aco_save_T	aco;
+
+    if (n > 0 && n <= buf->b_ml.ml_line_count)
+    {
+	/* set curwin/curbuf for "buf" and save some things */
+	aucmd_prepbuf(&aco, buf);
 
-    if (n > 0 && n <= buf->b_ml.ml_line_count) {
-	curbuf = buf;
 	if (u_savedel(n, 1) == OK) {
 	    ml_delete(n, 0);
 
@@ -691,10 +702,15 @@
 
 	    changed();
 	}
-	curbuf = savebuf;
+
+	/* restore curwin/curbuf and a few other things */
+	aucmd_restbuf(&aco);
+	/* Careful: autocommands may have made "buf" invalid! */
+
 	update_curbuf(NOT_VALID);
     }
-    else {
+    else
+    {
 	rb_raise(rb_eIndexError, "index %d out of buffer", n);
     }
     return Qnil;
@@ -702,13 +718,16 @@
 
 static VALUE buffer_append(VALUE self, VALUE num, VALUE str)
 {
-    buf_T *buf = get_buf(self);
-    buf_T *savebuf = curbuf;
-    char *line = STR2CSTR(str);
-    long n = NUM2LONG(num);
+    buf_T	*buf = get_buf(self);
+    char	*line = STR2CSTR(str);
+    long	n = NUM2LONG(num);
+    aco_save_T	aco;
+
+    if (n >= 0 && n <= buf->b_ml.ml_line_count && line != NULL)
+    {
+	/* set curwin/curbuf for "buf" and save some things */
+	aucmd_prepbuf(&aco, buf);
 
-    if (n >= 0 && n <= buf->b_ml.ml_line_count && line != NULL) {
-	curbuf = buf;
 	if (u_inssub(n + 1) == OK) {
 	    ml_append(n, (char_u *) line, (colnr_T) 0, FALSE);
 
@@ -718,7 +737,11 @@
 
 	    changed();
 	}
-	curbuf = savebuf;
+
+	/* restore curwin/curbuf and a few other things */
+	aucmd_restbuf(&aco);
+	/* Careful: autocommands may have made "buf" invalid! */
+
 	update_curbuf(NOT_VALID);
     }
     else {
diff -Naur vim70.orig/src/macros.h vim70/src/macros.h
--- vim70.orig/src/macros.h	2006-03-01 04:01:10.000000000 -0800
+++ vim70/src/macros.h	2006-11-29 16:10:04.000000000 -0800
@@ -276,3 +276,9 @@
 # define MB_CHARLEN(p)		STRLEN(p)
 # define PTR2CHAR(p)		((int)*(p))
 #endif
+
+#ifdef FEAT_AUTOCHDIR
+# define DO_AUTOCHDIR if (p_acd) do_autochdir();
+#else
+# define DO_AUTOCHDIR
+#endif
diff -Naur vim70.orig/src/main.c vim70/src/main.c
--- vim70.orig/src/main.c	2006-05-03 10:36:44.000000000 -0700
+++ vim70/src/main.c	2006-11-29 16:10:15.000000000 -0800
@@ -564,7 +564,11 @@
      */
     if (p_lpl)
     {
+# ifdef VMS	/* Somehow VMS doesn't handle the "**". */
+	source_runtime((char_u *)"plugin/*.vim", TRUE);
+# else
 	source_runtime((char_u *)"plugin/**/*.vim", TRUE);
+# endif
 	TIME_MSG("loading plugins");
     }
 #endif
@@ -1126,6 +1130,16 @@
 	 */
 	update_curswant();
 
+#ifdef FEAT_EVAL
+	/*
+	 * May perform garbage collection when waiting for a character, but
+	 * only at the very toplevel.  Otherwise we may be using a List or
+	 * Dict internally somewhere.
+	 * "may_garbage_collect" is reset in vgetc() which is invoked through
+	 * do_exmode() and normal_cmd().
+	 */
+	may_garbage_collect = (!cmdwin && !noexmode);
+#endif
 	/*
 	 * If we're invoked as ex, do a round of ex commands.
 	 * Otherwise, get and execute a normal mode command.
@@ -2281,7 +2295,7 @@
     mparm_T	*parmp;
 {
 #ifdef FEAT_WINDOWS
-    int		rewind;
+    int		dorewind;
     int		done = 0;
 
     /*
@@ -2338,10 +2352,10 @@
 	++autocmd_no_leave;
 #endif
 #ifdef FEAT_WINDOWS
-	rewind = TRUE;
+	dorewind = TRUE;
 	while (done++ < 1000)
 	{
-	    if (rewind)
+	    if (dorewind)
 	    {
 		if (parmp->window_layout == WIN_TABS)
 		    goto_tabpage(1);
@@ -2360,7 +2374,7 @@
 		    break;
 		curwin = curwin->w_next;
 	    }
-	    rewind = FALSE;
+	    dorewind = FALSE;
 #endif
 	    curbuf = curwin->w_buffer;
 	    if (curbuf->b_ml.ml_mfp == NULL)
@@ -2378,10 +2392,26 @@
 		(void)open_buffer(FALSE, NULL); /* create memfile, read file */
 
 #if defined(HAS_SWAP_EXISTS_ACTION)
-		check_swap_exists_action();
+		if (swap_exists_action == SEA_QUIT)
+		{
+		    if (got_int || only_one_window())
+		    {
+			/* abort selected or quit and only one window */
+			did_emsg = FALSE;   /* avoid hit-enter prompt */
+			getout(1);
+		    }
+		    /* We can't close the window, it would disturb what
+		     * happens next.  Clear the file name and set the arg
+		     * index to -1 to delete it later. */
+		    setfname(curbuf, NULL, NULL, FALSE);
+		    curwin->w_arg_idx = -1;
+		    swap_exists_action = SEA_NONE;
+		}
+		else
+		    handle_swap_exists(NULL);
 #endif
 #ifdef FEAT_AUTOCMD
-		rewind = TRUE;		/* start again */
+		dorewind = TRUE;		/* start again */
 #endif
 	    }
 #ifdef FEAT_WINDOWS
@@ -2418,6 +2448,8 @@
 {
     int		arg_idx;		/* index in argument list */
     int		i;
+    int		advance = TRUE;
+    buf_T	*old_curbuf;
 
 # ifdef FEAT_AUTOCMD
     /*
@@ -2426,31 +2458,65 @@
     ++autocmd_no_enter;
     ++autocmd_no_leave;
 # endif
+
+    /* When w_arg_idx is -1 remove the window (see create_windows()). */
+    if (curwin->w_arg_idx == -1)
+    {
+	win_close(curwin, TRUE);
+	advance = FALSE;
+    }
+
     arg_idx = 1;
     for (i = 1; i < parmp->window_count; ++i)
     {
-	if (parmp->window_layout == WIN_TABS)
+	/* When w_arg_idx is -1 remove the window (see create_windows()). */
+	if (curwin->w_arg_idx == -1)
 	{
-	    if (curtab->tp_next == NULL)	/* just checking */
-		break;
-	    goto_tabpage(0);
+	    ++arg_idx;
+	    win_close(curwin, TRUE);
+	    advance = FALSE;
+	    continue;
 	}
-	else
+
+	if (advance)
 	{
-	    if (curwin->w_next == NULL)		/* just checking */
-		break;
-	    win_enter(curwin->w_next, FALSE);
+	    if (parmp->window_layout == WIN_TABS)
+	    {
+		if (curtab->tp_next == NULL)	/* just checking */
+		    break;
+		goto_tabpage(0);
+	    }
+	    else
+	    {
+		if (curwin->w_next == NULL)	/* just checking */
+		    break;
+		win_enter(curwin->w_next, FALSE);
+	    }
 	}
+	advance = TRUE;
 
 	/* Only open the file if there is no file in this window yet (that can
-	 * happen when .vimrc contains ":sall") */
+	 * happen when .vimrc contains ":sall"). */
 	if (curbuf == firstwin->w_buffer || curbuf->b_ffname == NULL)
 	{
 	    curwin->w_arg_idx = arg_idx;
-	    /* edit file from arg list, if there is one */
+	    /* Edit file from arg list, if there is one.  When "Quit" selected
+	     * at the ATTENTION prompt close the window. */
+	    old_curbuf = curbuf;
 	    (void)do_ecmd(0, arg_idx < GARGCOUNT
 			  ? alist_name(&GARGLIST[arg_idx]) : NULL,
 			  NULL, NULL, ECMD_LASTL, ECMD_HIDE);
+	    if (curbuf == old_curbuf)
+	    {
+		if (got_int || only_one_window())
+		{
+		    /* abort selected or quit and only one window */
+		    did_emsg = FALSE;   /* avoid hit-enter prompt */
+		    getout(1);
+		}
+		win_close(curwin, TRUE);
+		advance = FALSE;
+	    }
 	    if (arg_idx == GARGCOUNT - 1)
 		arg_had_last = TRUE;
 	    ++arg_idx;
@@ -3208,10 +3274,15 @@
      * Register for remote command execution with :serversend and --remote
      * unless there was a -X or a --servername '' on the command line.
      * Only register nongui-vim's with an explicit --servername argument.
+     * When running as root --servername is also required.
      */
     if (X_DISPLAY != NULL && parmp->servername != NULL && (
 #  ifdef FEAT_GUI
-		gui.in_use ||
+		(gui.in_use
+#   ifdef UNIX
+		 && getuid() != 0
+#   endif
+		) ||
 #  endif
 		parmp->serverName_arg != NULL))
     {
diff -Naur vim70.orig/src/Makefile vim70/src/Makefile
--- vim70.orig/src/Makefile	2006-05-07 06:25:27.000000000 -0700
+++ vim70/src/Makefile	2006-11-29 16:10:01.000000000 -0800
@@ -2177,6 +2177,7 @@
 	cd $(SHADOWDIR)/xxd; ln -s ../../xxd/*.[ch] ../../xxd/Make* .
 	if test -d $(RSRC_DIR); then \
 		cd $(SHADOWDIR); \
+		ln -s ../infplist.xml .; \
 		ln -s ../$(RSRC_DIR) ../os_mac.rsr.hqx ../dehqx.py .; \
 	fi
 	mkdir $(SHADOWDIR)/testdir
@@ -2260,7 +2261,7 @@
 auto/osdef.h: auto/config.h osdef.sh osdef1.h.in osdef2.h.in
 	CC="$(CC) $(OSDEF_CFLAGS)" srcdir=$(srcdir) sh $(srcdir)/osdef.sh
 
-QUOTESED = sed -e 's/"/\\"/g' -e 's/\\"/"/' -e 's/\\";$$/";/'
+QUOTESED = sed -e 's/[\\"]/\\&/g' -e 's/\\"/"/' -e 's/\\";$$/";/'
 auto/pathdef.c: Makefile auto/config.mk
 	-@echo creating $@
 	-@echo '/* pathdef.c */' > $@
diff -Naur vim70.orig/src/mbyte.c vim70/src/mbyte.c
--- vim70.orig/src/mbyte.c	2006-04-30 04:51:01.000000000 -0700
+++ vim70/src/mbyte.c	2006-11-29 16:09:58.000000000 -0800
@@ -311,7 +311,11 @@
 
 #define IDX_MACROMAN	57
     {"macroman",	ENC_8BIT + ENC_MACROMAN, 0},	/* Mac OS */
-#define IDX_COUNT	58
+#define IDX_DECMCS	58
+    {"dec-mcs",		ENC_8BIT,		0},	/* DEC MCS */
+#define IDX_HPROMAN8	59
+    {"hp-roman8",	ENC_8BIT,		0},	/* HP Roman8 */
+#define IDX_COUNT	60
 };
 
 /*
@@ -359,6 +363,8 @@
     {"932",		IDX_CP932},
     {"949",		IDX_CP949},
     {"936",		IDX_CP936},
+    {"gbk",		IDX_CP936},
+    {"gb18030",		IDX_CP936},	/* only 99% the same */
     {"950",		IDX_CP950},
     {"eucjp",		IDX_EUC_JP},
     {"unix-jis",	IDX_EUC_JP},
@@ -386,6 +392,7 @@
     {"950",		IDX_BIG5},
 #endif
     {"mac",		IDX_MACROMAN},
+    {"mac-roman",	IDX_MACROMAN},
     {NULL,		0}
 };
 
@@ -3507,6 +3514,11 @@
 	add_to_input_buf(delkey, (int)sizeof(delkey));
 }
 
+/*
+ * Move the cursor left by "num_move_back" characters.
+ * Note that ins_left() checks im_is_preediting() to avoid breaking undo for
+ * these K_LEFT keys.
+ */
     static void
 im_correct_cursor(int num_move_back)
 {
@@ -3734,8 +3746,7 @@
     }
     else if (cursor_index == 0 && preedit_string[0] == '\0')
     {
-	if (preedit_start_col == MAXCOL)
-	    xim_has_preediting = FALSE;
+	xim_has_preediting = FALSE;
 
 	/* If at the start position (after typing backspace)
 	 * preedit_start_col must be reset. */
@@ -3850,13 +3861,13 @@
 
     if (preedit_string != NULL && attr_list != NULL)
     {
-	int index;
+	int idx;
 
 	/* Get the byte index as used by PangoAttrIterator */
-	for (index = 0; col > 0 && preedit_string[index] != '\0'; --col)
-	    index += utfc_ptr2len((char_u *)preedit_string + index);
+	for (idx = 0; col > 0 && preedit_string[idx] != '\0'; --col)
+	    idx += utfc_ptr2len((char_u *)preedit_string + idx);
 
-	if (preedit_string[index] != '\0')
+	if (preedit_string[idx] != '\0')
 	{
 	    PangoAttrIterator	*iter;
 	    int			start, end;
@@ -3869,7 +3880,7 @@
 	    {
 		pango_attr_iterator_range(iter, &start, &end);
 
-		if (index >= start && index < end)
+		if (idx >= start && idx < end)
 		    char_attr |= translate_pango_attributes(iter);
 	    }
 	    while (pango_attr_iterator_next(iter));
diff -Naur vim70.orig/src/memfile.c vim70/src/memfile.c
--- vim70.orig/src/memfile.c	2006-03-06 00:59:15.000000000 -0800
+++ vim70/src/memfile.c	2006-11-29 16:10:14.000000000 -0800
@@ -517,7 +517,7 @@
 	mf_ins_free(mfp, hp);	/* put *hp in the free list */
 }
 
-#if defined(__MORPHOS__)
+#if defined(__MORPHOS__) && defined(__libnix__)
 /* function is missing in MorphOS libnix version */
 extern unsigned long *__stdfiledes;
 
@@ -677,15 +677,19 @@
 #  else
 #   if defined(_DCC) || defined(__GNUC__) || defined(__MORPHOS__)
 	{
-#    if defined(__GNUC__) && !defined(__MORPHOS__)
+#    if defined(__GNUC__) && !defined(__MORPHOS__) && defined(__libnix__)
 	    /* Have function (in libnix at least),
 	     * but ain't got no prototype anywhere. */
 	    extern unsigned long fdtofh(int filedescriptor);
 #    endif
+#    if !defined(__libnix__)
+	    fflush(NULL);
+#    else
 	    BPTR fh = (BPTR)fdtofh(mfp->mf_fd);
 
 	    if (fh != 0)
 		Flush(fh);
+#    endif
 	}
 #   else /* assume Manx */
 	    Flush(_devtab[mfp->mf_fd].fd);
@@ -1024,12 +1028,12 @@
     size = page_size * hp->bh_page_count;
     if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset)
     {
-	EMSG(_("E294: Seek error in swap file read"));
+	PERROR(_("E294: Seek error in swap file read"));
 	return FAIL;
     }
     if ((unsigned)vim_read(mfp->mf_fd, hp->bh_data, size) != size)
     {
-	EMSG(_("E295: Read error in swap file"));
+	PERROR(_("E295: Read error in swap file"));
 	return FAIL;
     }
     return OK;
@@ -1081,7 +1085,7 @@
 	offset = (off_t)page_size * nr;
 	if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset)
 	{
-	    EMSG(_("E296: Seek error in swap file write"));
+	    PERROR(_("E296: Seek error in swap file write"));
 	    return FAIL;
 	}
 	if (hp2 == NULL)	    /* freed block, fill with dummy data */
diff -Naur vim70.orig/src/memline.c vim70/src/memline.c
--- vim70.orig/src/memline.c	2006-04-20 14:00:21.000000000 -0700
+++ vim70/src/memline.c	2006-11-29 16:10:15.000000000 -0800
@@ -215,7 +215,7 @@
 #define ML_FLUSH	0x02	    /* flush locked block */
 #define ML_SIMPLE(x)	(x & 0x10)  /* DEL, INS or FIND */
 
-static void ml_upd_block0 __ARGS((buf_T *buf, int setfname));
+static void ml_upd_block0 __ARGS((buf_T *buf, int set_fname));
 static void set_b0_fname __ARGS((ZERO_BL *, buf_T *buf));
 static void set_b0_dir_flag __ARGS((ZERO_BL *b0p, buf_T *buf));
 #ifdef FEAT_MBYTE
@@ -679,9 +679,9 @@
  * Update the timestamp or the B0_SAME_DIR flag of the .swp file.
  */
     static void
-ml_upd_block0(buf, setfname)
+ml_upd_block0(buf, set_fname)
     buf_T	*buf;
-    int		setfname;
+    int		set_fname;
 {
     memfile_T	*mfp;
     bhdr_T	*hp;
@@ -695,7 +695,7 @@
 	EMSG(_("E304: ml_upd_block0(): Didn't get block 0??"));
     else
     {
-	if (setfname)
+	if (set_fname)
 	    set_b0_fname(b0p, buf);
 	else
 	    set_b0_dir_flag(b0p, buf);
@@ -1325,6 +1325,7 @@
 	    mf_put(mfp, hp, FALSE, FALSE);
 	mf_close(mfp, FALSE);	    /* will also vim_free(mfp->mf_fname) */
     }
+    vim_free(buf->b_ml.ml_stack);
     vim_free(buf);
     if (serious_error && called_from_main)
 	ml_close(curbuf, TRUE);
@@ -1633,6 +1634,7 @@
     int		    fd;
     struct block0   b0;
     time_t	    x = (time_t)0;
+    char	    *p;
 #ifdef UNIX
     char_u	    uname[B0_UNAME_SIZE];
 #endif
@@ -1652,8 +1654,11 @@
 #endif
 	    MSG_PUTS(_("             dated: "));
 	x = st.st_mtime;		    /* Manx C can't do &st.st_mtime */
-	MSG_PUTS(ctime(&x));		    /* includes '\n' */
-
+	p = ctime(&x);			    /* includes '\n' */
+	if (p == NULL)
+	    MSG_PUTS("(invalid)\n");
+	else
+	    MSG_PUTS(p);
     }
 
     /*
@@ -3652,6 +3657,7 @@
 {
     struct stat st;
     time_t	x, sx;
+    char	*p;
 
     ++no_wait_return;
     (void)EMSG(_("E325: ATTENTION"));
@@ -3666,7 +3672,11 @@
     {
 	MSG_PUTS(_("             dated: "));
 	x = st.st_mtime;    /* Manx C can't do &st.st_mtime */
-	MSG_PUTS(ctime(&x));
+	p = ctime(&x);			    /* includes '\n' */
+	if (p == NULL)
+	    MSG_PUTS("(invalid)\n");
+	else
+	    MSG_PUTS(p);
 	if (sx != 0 && x > sx)
 	    MSG_PUTS(_("      NEWER than swap file!\n"));
     }
diff -Naur vim70.orig/src/menu.c vim70/src/menu.c
--- vim70.orig/src/menu.c	2006-05-03 10:30:48.000000000 -0700
+++ vim70/src/menu.c	2006-11-29 16:09:56.000000000 -0800
@@ -511,6 +511,14 @@
 	 * name (without mnemonic and accelerator text). */
 	next_name = menu_name_skip(name);
 	dname = menu_text(name, NULL, NULL);
+	if (dname == NULL)
+	    goto erret;
+	if (*dname == NUL)
+	{
+	    /* Only a mnemonic or accelerator is not valid. */
+	    EMSG(_("E792: Empty menu name"));
+	    goto erret;
+	}
 
 	/* See if it's already there */
 	lower_pri = menup;
@@ -704,6 +712,7 @@
 	parent = menu;
 	name = next_name;
 	vim_free(dname);
+	dname = NULL;
 	if (pri_tab[pri_idx + 1] != -1)
 	    ++pri_idx;
     }
@@ -793,6 +802,22 @@
 erret:
     vim_free(path_name);
     vim_free(dname);
+
+    /* Delete any empty submenu we added before discovering the error.  Repeat
+     * for higher levels. */
+    while (parent != NULL && parent->children == NULL)
+    {
+	if (parent->parent == NULL)
+	    menup = &root_menu;
+	else
+	    menup = &parent->parent->children;
+	for ( ; *menup != NULL && *menup != parent; menup = &((*menup)->next))
+	    ;
+	if (*menup == NULL) /* safety check */
+	    break;
+	parent = parent->parent;
+	free_menu(menup);
+    }
     return FAIL;
 }
 
@@ -1753,6 +1778,27 @@
 }
 
 /*
+ * Check that a pointer appears in the menu tree.  Used to protect from using
+ * a menu that was deleted after it was selected but before the event was
+ * handled.
+ * Return OK or FAIL.  Used recursively.
+ */
+    int
+check_menu_pointer(root, menu_to_check)
+    vimmenu_T *root;
+    vimmenu_T *menu_to_check;
+{
+    vimmenu_T	*p;
+
+    for (p = root; p != NULL; p = p->next)
+	if (p == menu_to_check
+		|| (p->children != NULL
+		    && check_menu_pointer(p->children, menu_to_check) == OK))
+	    return OK;
+    return FAIL;
+}
+
+/*
  * After we have started the GUI, then we can create any menus that have been
  * defined.  This is done once here.  add_menu_path() may have already been
  * called to define these menus, and may be called again.  This function calls
diff -Naur vim70.orig/src/message.c vim70/src/message.c
--- vim70.orig/src/message.c	2006-05-06 13:07:37.000000000 -0700
+++ vim70/src/message.c	2006-11-29 16:10:10.000000000 -0800
@@ -53,7 +53,6 @@
 static struct msg_hist *first_msg_hist = NULL;
 static struct msg_hist *last_msg_hist = NULL;
 static int msg_hist_len = 0;
-static int msg_hist_off = FALSE;	/* don't add messages to history */
 
 /*
  * When writing messages to the screen, there are many different situations.
@@ -1925,7 +1924,8 @@
 	     * If screen is completely filled and 'more' is set then wait
 	     * for a character.
 	     */
-	    if (p_more && --lines_left == 0 && State != HITRETURN
+	    --lines_left;
+	    if (p_more && lines_left == 0 && State != HITRETURN
 					    && !msg_no_more && !exmode_active)
 	    {
 #ifdef FEAT_CON_DIALOG
@@ -4123,8 +4123,6 @@
 	    case 'c':
 	    case 's':
 		length_modifier = '\0';
-		zero_padding = 0;    /* turn zero padding off for string
-					conversions */
 		str_arg_l = 1;
 		switch (fmt_spec)
 		{
@@ -4175,15 +4173,16 @@
 			str_arg_l = 0;
 		    else
 		    {
-			/* memchr on HP does not like n > 2^31  !!! */
-			char *q = memchr(str_arg, '\0',
+			/* Don't put the #if inside memchr(), it can be a
+			 * macro. */
 #if SIZEOF_INT <= 2
-				precision
+			char *q = memchr(str_arg, '\0', precision);
 #else
-				precision <= (size_t)0x7fffffffL ? precision
-						       : (size_t)0x7fffffffL
+			/* memchr on HP does not like n > 2^31  !!! */
+			char *q = memchr(str_arg, '\0',
+				  precision <= (size_t)0x7fffffffL ? precision
+						       : (size_t)0x7fffffffL);
 #endif
-						       );
 			str_arg_l = (q == NULL) ? precision : q - str_arg;
 		    }
 		    break;
diff -Naur vim70.orig/src/misc1.c vim70/src/misc1.c
--- vim70.orig/src/misc1.c	2006-04-30 08:30:02.000000000 -0700
+++ vim70/src/misc1.c	2006-11-29 16:10:13.000000000 -0800
@@ -1761,15 +1761,13 @@
      * Add column offset for 'number', 'foldcolumn', etc.
      */
     width = W_WIDTH(wp) - win_col_off(wp);
-    if (width > 0)
-    {
-	lines += 1;
-	if (col >= width)
-	    lines += (col - width) / (width + win_col_off2(wp));
-	if (lines <= wp->w_height)
-	    return lines;
-    }
-    return (int)(wp->w_height);	    /* maximum length */
+    if (width <= 0)
+	return 9999;
+
+    lines += 1;
+    if (col > width)
+	lines += (col - width) / (width + win_col_off2(wp)) + 1;
+    return lines;
 }
 
     int
@@ -2842,7 +2840,8 @@
 
 #ifdef FEAT_AUTOCMD
     /* when the cursor line is changed always trigger CursorMoved */
-    if (lnum <= curwin->w_cursor.lnum && lnume > curwin->w_cursor.lnum)
+    if (lnum <= curwin->w_cursor.lnum
+		 && lnume + (xtra < 0 ? -xtra : xtra) > curwin->w_cursor.lnum)
 	last_cursormoved.lnum = 0;
 #endif
 }
@@ -3016,6 +3015,7 @@
     int		len = 0;
     int		n;
     int		save_mapped_ctrl_c = mapped_ctrl_c;
+    int		waited = 0;
 
     mapped_ctrl_c = FALSE;	/* mappings are not used here */
     for (;;)
@@ -3034,11 +3034,16 @@
 	    /* Replace zero and CSI by a special key code. */
 	    n = fix_input_buffer(buf + len, n, FALSE);
 	    len += n;
+	    waited = 0;
 	}
+	else if (len > 0)
+	    ++waited;	    /* keep track of the waiting time */
 
-	/* incomplete termcode: get more characters */
-	if ((n = check_termcode(1, buf, len)) < 0)
+	/* Incomplete termcode and not timed out yet: get more characters */
+	if ((n = check_termcode(1, buf, len)) < 0
+	       && (!p_ttimeout || waited * 100L < (p_ttm < 0 ? p_tm : p_ttm)))
 	    continue;
+
 	/* found a termcode: adjust length */
 	if (n > 0)
 	    len = n;
@@ -3196,14 +3201,12 @@
     else
 	MSG_PUTS(_("Choice number (<Enter> cancels): "));
 
-    /* Set the state such that text can be selected/copied/pasted. */
+    /* Set the state such that text can be selected/copied/pasted and we still
+     * get mouse events. */
     save_cmdline_row = cmdline_row;
-    cmdline_row = Rows - 1;
+    cmdline_row = 0;
     save_State = State;
-    if (mouse_used == NULL)
-	State = CMDLINE;
-    else
-	State = NORMAL;
+    State = CMDLINE;
 
     i = get_number(TRUE, mouse_used);
     if (KeyTyped)
@@ -4492,7 +4495,7 @@
 		int l = mb_ptr2len(s);
 
 		while (--l > 0)
-		    *d++ = *s++;
+		    *d++ = *++s;
 	    }
 # endif
 	}
@@ -8070,9 +8073,20 @@
 		}
 		if (*that == '"' && *(that + 1) != NUL)
 		{
-		    that++;
-		    while (*that && (*that != '"' || *(that - 1) == '\\'))
-			++that;
+		    while (*++that && *that != '"')
+		    {
+			/* skipping escaped characters in the string */
+			if (*that == '\\')
+			{
+			    if (*++that == NUL)
+				break;
+			    if (that[1] == NUL)
+			    {
+				++that;
+				break;
+			    }
+			}
+		    }
 		}
 		if (*that == '(' || *that == '[')
 		    ++parencount;
diff -Naur vim70.orig/src/misc2.c vim70/src/misc2.c
--- vim70.orig/src/misc2.c	2006-05-04 05:12:38.000000000 -0700
+++ vim70/src/misc2.c	2006-11-29 16:10:08.000000000 -0800
@@ -1229,6 +1229,94 @@
     return escaped_string;
 }
 
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Escape "string" for use as a shell argument with system().
+ * This uses single quotes, except when we know we need to use double qoutes
+ * (MS-DOS and MS-Windows without 'shellslash' set).
+ * Returns the result in allocated memory, NULL if we have run out.
+ */
+    char_u *
+vim_strsave_shellescape(string)
+    char_u	*string;
+{
+    unsigned	length;
+    char_u	*p;
+    char_u	*d;
+    char_u	*escaped_string;
+
+    /* First count the number of extra bytes required. */
+    length = STRLEN(string) + 3;	/* two quotes and the trailing NUL */
+    for (p = string; *p != NUL; mb_ptr_adv(p))
+    {
+# if defined(WIN32) || defined(WIN16) || defined(DOS)
+	if (!p_ssl)
+	{
+	    if (*p == '"')
+		++length;		/* " -> "" */
+	}
+	else
+# endif
+	if (*p == '\'')
+	    length += 3;		/* ' => '\'' */
+    }
+
+    /* Allocate memory for the result and fill it. */
+    escaped_string = alloc(length);
+    if (escaped_string != NULL)
+    {
+	d = escaped_string;
+
+	/* add opening quote */
+# if defined(WIN32) || defined(WIN16) || defined(DOS)
+	if (!p_ssl)
+	    *d++ = '"';
+	else
+# endif
+	    *d++ = '\'';
+
+	for (p = string; *p != NUL; )
+	{
+# if defined(WIN32) || defined(WIN16) || defined(DOS)
+	    if (!p_ssl)
+	    {
+		if (*p == '"')
+		{
+		    *d++ = '"';
+		    *d++ = '"';
+		    ++p;
+		    continue;
+		}
+	    }
+	    else
+# endif
+	    if (*p == '\'')
+	    {
+		*d++='\'';
+		*d++='\\';
+		*d++='\'';
+		*d++='\'';
+		++p;
+		continue;
+	    }
+
+	    MB_COPY_CHAR(p, d);
+	}
+
+	/* add terminating quote and finish with a NUL */
+# if defined(WIN32) || defined(WIN16) || defined(DOS)
+	if (!p_ssl)
+	    *d++ = '"';
+	else
+# endif
+	    *d++ = '\'';
+	*d = NUL;
+    }
+
+    return escaped_string;
+}
+#endif
+
 /*
  * Like vim_strsave(), but make all characters uppercase.
  * This uses ASCII lower-to-upper case translation, language independent.
diff -Naur vim70.orig/src/netbeans.c vim70/src/netbeans.c
--- vim70.orig/src/netbeans.c	2006-04-22 11:00:05.000000000 -0700
+++ vim70/src/netbeans.c	2006-11-29 16:10:15.000000000 -0800
@@ -61,7 +61,7 @@
 
 /* The first implementation (working only with Netbeans) returned "1.1".  The
  * protocol implemented here also supports A-A-P. */
-static char *ExtEdProtocolVersion = "2.3";
+static char *ExtEdProtocolVersion = "2.4";
 
 static long pos2off __ARGS((buf_T *, pos_T *));
 static pos_T *off2pos __ARGS((buf_T *, long));
@@ -103,7 +103,7 @@
 static int  inputHandler = -1;		/* simply ret.value of WSAAsyncSelect() */
 extern HWND s_hwnd;			/* Gvim's Window handle */
 #endif
-static int cmdno;			/* current command number for reply */
+static int r_cmdno;			/* current command number for reply */
 static int haveConnection = FALSE;	/* socket is connected and
 					   initialization is done */
 #ifdef FEAT_GUI_MOTIF
@@ -832,11 +832,11 @@
 	return;
     }
 
-    cmdno = strtol(q, &q, 10);
+    r_cmdno = strtol(q, &q, 10);
 
     q = (char *)skipwhite((char_u *)q);
 
-    if (nb_do_cmd(bufno, (char_u *)verb, isfunc, cmdno, (char_u *)q) == FAIL)
+    if (nb_do_cmd(bufno, (char_u *)verb, isfunc, r_cmdno, (char_u *)q) == FAIL)
     {
 #ifdef NBDEBUG
 	/*
@@ -1008,11 +1008,11 @@
 	if (netbeansForcedQuit)
 	{
 	    /* mark as unmodified so NetBeans won't put up dialog on "killed" */
-	    sprintf(buf, "%d:unmodified=%d\n", i, cmdno);
+	    sprintf(buf, "%d:unmodified=%d\n", i, r_cmdno);
 	    nbdebug(("EVT: %s", buf));
 	    nb_send(buf, "netbeans_end");
 	}
-	sprintf(buf, "%d:killed=%d\n", i, cmdno);
+	sprintf(buf, "%d:killed=%d\n", i, r_cmdno);
 	nbdebug(("EVT: %s", buf));
 /*	nb_send(buf, "netbeans_end");    avoid "write failed" messages */
 	if (sd >= 0)
@@ -1271,6 +1271,29 @@
 	    nb_reply_text(cmdno, text);
 /* =====================================================================*/
 	}
+	else if (streq((char *)cmd, "getAnno"))
+	{
+	    long linenum = 0;
+#ifdef FEAT_SIGNS
+	    if (buf == NULL || buf->bufp == NULL)
+	    {
+		nbdebug(("    null bufp in getAnno"));
+		EMSG("E652: null bufp in getAnno");
+		retval = FAIL;
+	    }
+	    else
+	    {
+		int serNum;
+
+		cp = (char *)args;
+		serNum = strtol(cp, &cp, 10);
+		/* If the sign isn't found linenum will be zero. */
+		linenum = (long)buf_findsign(buf->bufp, serNum);
+	    }
+#endif
+	    nb_reply_nr(cmdno, linenum);
+/* =====================================================================*/
+	}
 	else if (streq((char *)cmd, "getLength"))
 	{
 	    long len = 0;
@@ -1986,6 +2009,8 @@
 	    if (buf->bufp != NULL)
 		do_buffer(DOBUF_WIPE, DOBUF_FIRST, FORWARD,
 						     buf->bufp->b_fnum, TRUE);
+	    buf->bufp = NULL;
+	    buf->initDone = FALSE;
 	    doupdate = 1;
 /* =====================================================================*/
 	}
@@ -2561,7 +2586,7 @@
 	    if (p != NULL)
 	    {
 		vim_snprintf(buf, sizeof(buf),
-				       "0:balloonText=%d \"%s\"\n", cmdno, p);
+				       "0:balloonText=%d \"%s\"\n", r_cmdno, p);
 		vim_free(p);
 	    }
 	    nbdebug(("EVT: %s", buf));
@@ -2615,7 +2640,7 @@
 
     if (haveConnection)
     {
-	sprintf(buf, "0:disconnect=%d\n", cmdno);
+	sprintf(buf, "0:disconnect=%d\n", r_cmdno);
 	nbdebug(("EVT: %s", buf));
 	nb_send(buf, "netbeans_disconnect");
     }
@@ -2634,7 +2659,7 @@
 	return;
 
     sprintf(buf, "0:geometry=%d %d %d %d %d\n",
-		    cmdno, (int)Columns, (int)Rows, new_x, new_y);
+		    r_cmdno, (int)Columns, (int)Rows, new_x, new_y);
     /*nbdebug(("EVT: %s", buf)); happens too many times during a move */
     nb_send(buf, "netbeans_frame_moved");
 }
@@ -2743,7 +2768,7 @@
     if (bufno <= 0)
 	return;
 
-    sprintf(buffer, "%d:killed=%d\n", bufno, cmdno);
+    sprintf(buffer, "%d:killed=%d\n", bufno, r_cmdno);
 
     nbdebug(("EVT: %s", buffer));
 
@@ -2817,7 +2842,8 @@
     if (p != NULL)
     {
 	buf = alloc(128 + 2*newlen);
-	sprintf((char *)buf, "%d:insert=%d %ld \"%s\"\n", bufno, cmdno, off, p);
+	sprintf((char *)buf, "%d:insert=%d %ld \"%s\"\n",
+						      bufno, r_cmdno, off, p);
 	nbdebug(("EVT: %s", buf));
 	nb_send((char *)buf, "netbeans_inserted");
 	vim_free(p);
@@ -2859,7 +2885,7 @@
 
     off = pos2off(bufp, &pos);
 
-    sprintf((char *)buf, "%d:remove=%d %ld %ld\n", bufno, cmdno, off, len);
+    sprintf((char *)buf, "%d:remove=%d %ld %ld\n", bufno, r_cmdno, off, len);
     nbdebug(("EVT: %s", buf));
     nb_send((char *)buf, "netbeans_removed");
 }
@@ -2884,7 +2910,7 @@
 
     nbbuf->modified = 0;
 
-    sprintf((char *)buf, "%d:unmodified=%d\n", bufno, cmdno);
+    sprintf((char *)buf, "%d:unmodified=%d\n", bufno, r_cmdno);
     nbdebug(("EVT: %s", buf));
     nb_send((char *)buf, "netbeans_unmodified");
 #endif
@@ -2908,11 +2934,11 @@
 	long off = pos2off(curbuf, &curwin->w_cursor);
 
 	/* sync the cursor position */
-	sprintf(buf, "%d:newDotAndMark=%d %ld %ld\n", bufno, cmdno, off, off);
+	sprintf(buf, "%d:newDotAndMark=%d %ld %ld\n", bufno, r_cmdno, off, off);
 	nbdebug(("EVT: %s", buf));
 	nb_send(buf, "netbeans_button_release[newDotAndMark]");
 
-	sprintf(buf, "%d:buttonRelease=%d %d %ld %d\n", bufno, cmdno,
+	sprintf(buf, "%d:buttonRelease=%d %d %ld %d\n", bufno, r_cmdno,
 				    button, (long)curwin->w_cursor.lnum, col);
 	nbdebug(("EVT: %s", buf));
 	nb_send(buf, "netbeans_button_release");
@@ -2973,7 +2999,7 @@
 
     /* sync the cursor position */
     off = pos2off(curbuf, &curwin->w_cursor);
-    sprintf(buf, "%d:newDotAndMark=%d %ld %ld\n", bufno, cmdno, off, off);
+    sprintf(buf, "%d:newDotAndMark=%d %ld %ld\n", bufno, r_cmdno, off, off);
     nbdebug(("EVT: %s", buf));
     nb_send(buf, "netbeans_keycommand");
 
@@ -2984,13 +3010,13 @@
 
     /* now send keyCommand event */
     vim_snprintf(buf, sizeof(buf), "%d:keyCommand=%d \"%s\"\n",
-						       bufno, cmdno, keyName);
+						     bufno, r_cmdno, keyName);
     nbdebug(("EVT: %s", buf));
     nb_send(buf, "netbeans_keycommand");
 
     /* New: do both at once and include the lnum/col. */
     vim_snprintf(buf, sizeof(buf), "%d:keyAtPos=%d \"%s\" %ld %ld/%ld\n",
-	    bufno, cmdno, keyName,
+	    bufno, r_cmdno, keyName,
 		off, (long)curwin->w_cursor.lnum, (long)curwin->w_cursor.col);
     nbdebug(("EVT: %s", buf));
     nb_send(buf, "netbeans_keycommand");
@@ -3013,7 +3039,7 @@
 
     nbbuf->modified = 0;
 
-    sprintf((char *)buf, "%d:save=%d\n", bufno, cmdno);
+    sprintf((char *)buf, "%d:save=%d\n", bufno, r_cmdno);
     nbdebug(("EVT: %s", buf));
     nb_send((char *)buf, "netbeans_save_buffer");
 }
@@ -3037,7 +3063,7 @@
     if (nbbuf->insertDone)
 	nbbuf->modified = 1;
 
-    sprintf((char *)buf, "%d:remove=%d 0 -1\n", bufno, cmdno);
+    sprintf((char *)buf, "%d:remove=%d 0 -1\n", bufno, r_cmdno);
     nbdebug(("EVT(suppressed): %s", buf));
 /*     nb_send(buf, "netbeans_deleted_all_lines"); */
 }
diff -Naur vim70.orig/src/normal.c vim70/src/normal.c
--- vim70.orig/src/normal.c	2006-04-29 06:11:18.000000000 -0700
+++ vim70/src/normal.c	2006-11-29 16:10:15.000000000 -0800
@@ -1477,14 +1477,17 @@
 	}
 	else if (VIsual_active)
 	{
-	    /* Save the current VIsual area for '< and '> marks, and "gv" */
-	    curbuf->b_visual.vi_start = VIsual;
-	    curbuf->b_visual.vi_end = curwin->w_cursor;
-	    curbuf->b_visual.vi_mode = VIsual_mode;
-	    curbuf->b_visual.vi_curswant = curwin->w_curswant;
+	    if (!gui_yank)
+	    {
+		/* Save the current VIsual area for '< and '> marks, and "gv" */
+		curbuf->b_visual.vi_start = VIsual;
+		curbuf->b_visual.vi_end = curwin->w_cursor;
+		curbuf->b_visual.vi_mode = VIsual_mode;
+		curbuf->b_visual.vi_curswant = curwin->w_curswant;
 # ifdef FEAT_EVAL
-	    curbuf->b_visual_mode_eval = VIsual_mode;
+		curbuf->b_visual_mode_eval = VIsual_mode;
 # endif
+	    }
 
 	    /* In Select mode, a linewise selection is operated upon like a
 	     * characterwise selection. */
@@ -2377,11 +2380,20 @@
 	    /*
 	     * If visual was active, yank the highlighted text and put it
 	     * before the mouse pointer position.
+	     * In Select mode replace the highlighted text with the clipboard.
 	     */
 	    if (VIsual_active)
 	    {
-		stuffcharReadbuff('y');
-		stuffcharReadbuff(K_MIDDLEMOUSE);
+		if (VIsual_select)
+		{
+		    stuffcharReadbuff(Ctrl_G);
+		    stuffReadbuff((char_u *)"\"+p");
+		}
+		else
+		{
+		    stuffcharReadbuff('y');
+		    stuffcharReadbuff(K_MIDDLEMOUSE);
+		}
 		do_always = TRUE;	/* ignore 'mouse' setting next time */
 		return FALSE;
 	    }
@@ -2504,7 +2516,8 @@
 	     * NOTE: Ignore right button down and drag mouse events.
 	     * Windows only shows the popup menu on the button up event.
 	     */
-#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_PHOTON)
+#if defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_GTK) \
+			  || defined(FEAT_GUI_PHOTON) || defined(FEAT_GUI_MAC)
 	    if (!is_click)
 		return FALSE;
 #endif
@@ -4126,7 +4139,7 @@
     int		save_p_ws;
     int		save_p_scs;
     int		retval = OK;
-    int		incl;
+    int		incll;
 
     if ((pat = alloc(len + 7)) == NULL)
 	return FAIL;
@@ -4146,7 +4159,7 @@
      * With "gd" Search back for the start of the current function, then go
      * back until a blank line.  If this fails go to line 1.
      */
-    if (!locally || !findpar(&incl, BACKWARD, 1L, '{', FALSE))
+    if (!locally || !findpar(&incll, BACKWARD, 1L, '{', FALSE))
     {
 	setpcmark();			/* Set in findpar() otherwise */
 	curwin->w_cursor.lnum = 1;
@@ -8847,7 +8860,7 @@
 #endif
     while (cap->count1-- && !got_int)
     {
-	if (do_execreg(cap->nchar, FALSE, FALSE) == FAIL)
+	if (do_execreg(cap->nchar, FALSE, FALSE, FALSE) == FAIL)
 	{
 	    clearopbeep(cap->oap);
 	    break;
diff -Naur vim70.orig/src/ops.c vim70/src/ops.c
--- vim70.orig/src/ops.c	2006-04-30 08:13:44.000000000 -0700
+++ vim70/src/ops.c	2006-11-29 16:10:15.000000000 -0800
@@ -95,8 +95,8 @@
 static void block_insert __ARGS((oparg_T *oap, char_u *s, int b_insert, struct block_def*bdp));
 #endif
 static int	stuff_yank __ARGS((int, char_u *));
-static void	put_reedit_in_typebuf __ARGS((void));
-static int	put_in_typebuf __ARGS((char_u *s, int colon));
+static void	put_reedit_in_typebuf __ARGS((int silent));
+static int	put_in_typebuf __ARGS((char_u *s, int colon, int silent));
 static void	stuffescaped __ARGS((char_u *arg, int literally));
 #ifdef FEAT_MBYTE
 static void	mb_adjust_opend __ARGS((oparg_T *oap));
@@ -770,6 +770,7 @@
 {
     char_u	*expr_copy;
     char_u	*rv;
+    static int	nested = 0;
 
     if (expr_line == NULL)
 	return NULL;
@@ -780,7 +781,14 @@
     if (expr_copy == NULL)
 	return NULL;
 
+    /* When we are invoked recursively limit the evaluation to 10 levels.
+     * Then return the string as-is. */
+    if (nested >= 10)
+	return expr_copy;
+
+    ++nested;
     rv = eval_to_string(expr_copy, NULL, TRUE);
+    --nested;
     vim_free(expr_copy);
     return rv;
 }
@@ -1112,10 +1120,11 @@
  * return FAIL for failure, OK otherwise
  */
     int
-do_execreg(regname, colon, addcr)
+do_execreg(regname, colon, addcr, silent)
     int	    regname;
     int	    colon;		/* insert ':' before each line */
     int	    addcr;		/* always add '\n' to end of line */
+    int	    silent;		/* set "silent" flag in typeahead buffer */
 {
     static int	lastc = NUL;
     long	i;
@@ -1165,9 +1174,9 @@
 	    /* When in Visual mode "'<,'>" will be prepended to the command.
 	     * Remove it when it's already there. */
 	    if (VIsual_active && STRNCMP(p, "'<,'>", 5) == 0)
-		retval = put_in_typebuf(p + 5, TRUE);
+		retval = put_in_typebuf(p + 5, TRUE, silent);
 	    else
-		retval = put_in_typebuf(p, TRUE);
+		retval = put_in_typebuf(p, TRUE, silent);
 	}
 	vim_free(p);
     }
@@ -1178,7 +1187,7 @@
 	p = get_expr_line();
 	if (p == NULL)
 	    return FAIL;
-	retval = put_in_typebuf(p, colon);
+	retval = put_in_typebuf(p, colon, silent);
 	vim_free(p);
     }
 #endif
@@ -1190,7 +1199,7 @@
 	    EMSG(_(e_noinstext));
 	    return FAIL;
 	}
-	retval = put_in_typebuf(p, colon);
+	retval = put_in_typebuf(p, colon, silent);
 	vim_free(p);
     }
     else
@@ -1205,20 +1214,20 @@
 	/*
 	 * Insert lines into typeahead buffer, from last one to first one.
 	 */
-	put_reedit_in_typebuf();
+	put_reedit_in_typebuf(silent);
 	for (i = y_current->y_size; --i >= 0; )
 	{
 	    /* insert NL between lines and after last line if type is MLINE */
 	    if (y_current->y_type == MLINE || i < y_current->y_size - 1
 								     || addcr)
 	    {
-		if (ins_typebuf((char_u *)"\n", remap, 0, TRUE, FALSE) == FAIL)
+		if (ins_typebuf((char_u *)"\n", remap, 0, TRUE, silent) == FAIL)
 		    return FAIL;
 	    }
-	    if (ins_typebuf(y_current->y_array[i], remap, 0, TRUE, FALSE)
+	    if (ins_typebuf(y_current->y_array[i], remap, 0, TRUE, silent)
 								      == FAIL)
 		return FAIL;
-	    if (colon && ins_typebuf((char_u *)":", remap, 0, TRUE, FALSE)
+	    if (colon && ins_typebuf((char_u *)":", remap, 0, TRUE, silent)
 								      == FAIL)
 		return FAIL;
 	}
@@ -1232,7 +1241,8 @@
  * used only after other typeahead has been processed.
  */
     static void
-put_reedit_in_typebuf()
+put_reedit_in_typebuf(silent)
+    int		silent;
 {
     char_u	buf[3];
 
@@ -1249,25 +1259,26 @@
 	    buf[0] = restart_edit == 'I' ? 'i' : restart_edit;
 	    buf[1] = NUL;
 	}
-	if (ins_typebuf(buf, REMAP_NONE, 0, TRUE, FALSE) == OK)
+	if (ins_typebuf(buf, REMAP_NONE, 0, TRUE, silent) == OK)
 	    restart_edit = NUL;
     }
 }
 
     static int
-put_in_typebuf(s, colon)
+put_in_typebuf(s, colon, silent)
     char_u	*s;
     int		colon;	    /* add ':' before the line */
+    int		silent;
 {
     int		retval = OK;
 
-    put_reedit_in_typebuf();
+    put_reedit_in_typebuf(silent);
     if (colon)
-	retval = ins_typebuf((char_u *)"\n", REMAP_YES, 0, TRUE, FALSE);
+	retval = ins_typebuf((char_u *)"\n", REMAP_YES, 0, TRUE, silent);
     if (retval == OK)
-	retval = ins_typebuf(s, REMAP_YES, 0, TRUE, FALSE);
+	retval = ins_typebuf(s, REMAP_YES, 0, TRUE, silent);
     if (colon && retval == OK)
-	retval = ins_typebuf((char_u *)":", REMAP_YES, 0, TRUE, FALSE);
+	retval = ins_typebuf((char_u *)":", REMAP_YES, 0, TRUE, silent);
     return retval;
 }
 
@@ -1472,9 +1483,10 @@
  * return FAIL for failure, OK otherwise
  */
     int
-cmdline_paste_reg(regname, literally)
+cmdline_paste_reg(regname, literally, remcr)
     int regname;
     int literally;	/* Insert text literally instead of "as typed" */
+    int remcr;		/* don't add trailing CR */
 {
     long	i;
 
@@ -1486,8 +1498,13 @@
     {
 	cmdline_paste_str(y_current->y_array[i], literally);
 
-	/* insert ^M between lines and after last line if type is MLINE */
-	if (y_current->y_type == MLINE || i < y_current->y_size - 1)
+	/* Insert ^M between lines and after last line if type is MLINE.
+	 * Don't do this when "remcr" is TRUE and the next line is empty. */
+	if (y_current->y_type == MLINE
+		|| (i < y_current->y_size - 1
+		    && !(remcr
+			&& i == y_current->y_size - 2
+			&& *y_current->y_array[i + 1] == NUL)))
 	    cmdline_paste_str((char_u *)"\r", literally);
 
 	/* Check for CTRL-C, in case someone tries to paste a few thousand
@@ -2413,6 +2430,7 @@
 	else
 	{
 	    curwin->w_cursor = oap->end;
+	    check_cursor_col();
 
 	    /* Works just like an 'i'nsert on the next character. */
 	    if (!lineempty(curwin->w_cursor.lnum)
@@ -3492,8 +3510,15 @@
 # endif
 	if (flags & PUT_CURSEND)
 	{
+	    colnr_T len;
+
 	    curwin->w_cursor = curbuf->b_op_end;
 	    curwin->w_cursor.col++;
+
+	    /* in Insert mode we might be after the NUL, correct for that */
+	    len = (colnr_T)STRLEN(ml_get_curline());
+	    if (curwin->w_cursor.col > len)
+		curwin->w_cursor.col = len;
 	}
 	else
 	    curwin->w_cursor.lnum = lnum;
diff -Naur vim70.orig/src/option.c vim70/src/option.c
--- vim70.orig/src/option.c	2006-05-03 10:32:28.000000000 -0700
+++ vim70/src/option.c	2006-11-29 16:10:11.000000000 -0800
@@ -2294,7 +2294,7 @@
 			    {(char_u *)0L, (char_u *)0L}
 #endif
 			    },
-    {"spellsuggest", "sps", P_STRING|P_VI_DEF|P_EXPAND|P_SECURE,
+    {"spellsuggest", "sps", P_STRING|P_VI_DEF|P_EXPAND|P_SECURE|P_COMMA,
 #ifdef FEAT_SPELL
 			    (char_u *)&p_sps, PV_NONE,
 			    {(char_u *)"best", (char_u *)0L}
@@ -3397,7 +3397,7 @@
 	}
 	else if (flags & P_NUM)
 	{
-	    if (varp == (char_u *)PV_SCROLL)
+	    if (options[opt_idx].indir == PV_SCROLL)
 		win_comp_scroll(curwin);
 	    else
 	    {
@@ -5227,13 +5227,13 @@
 	    case PV_STL:	return &curwin->w_p_stl_flags;
 #endif
 #ifdef FEAT_EVAL
+# ifdef FEAT_FOLDING
 	    case PV_FDE:	return &curwin->w_p_fde_flags;
 	    case PV_FDT:	return &curwin->w_p_fdt_flags;
+# endif
 # ifdef FEAT_BEVAL
 	    case PV_BEXPR:	return &curbuf->b_p_bexpr_flags;
 # endif
-#endif
-#if defined(FEAT_EVAL)
 # if defined(FEAT_CINDENT)
 	    case PV_INDE:	return &curbuf->b_p_inde_flags;
 # endif
@@ -5268,45 +5268,46 @@
     char_u	*s;
     char_u	**varp;
     int		both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
+    int		idx = opt_idx;
 
-    if (opt_idx == -1)		/* use name */
+    if (idx == -1)		/* use name */
     {
-	opt_idx = findoption(name);
-	if (opt_idx < 0)	/* not found (should not happen) */
+	idx = findoption(name);
+	if (idx < 0)	/* not found (should not happen) */
 	{
 	    EMSG2(_(e_intern2), "set_string_option_direct()");
 	    return;
 	}
     }
 
-    if (options[opt_idx].var == NULL)	/* can't set hidden option */
+    if (options[idx].var == NULL)	/* can't set hidden option */
 	return;
 
     s = vim_strsave(val);
     if (s != NULL)
     {
-	varp = (char_u **)get_varp_scope(&(options[opt_idx]),
+	varp = (char_u **)get_varp_scope(&(options[idx]),
 					       both ? OPT_LOCAL : opt_flags);
-	if ((opt_flags & OPT_FREE) && (options[opt_idx].flags & P_ALLOCED))
+	if ((opt_flags & OPT_FREE) && (options[idx].flags & P_ALLOCED))
 	    free_string_option(*varp);
 	*varp = s;
 
 	/* For buffer/window local option may also set the global value. */
 	if (both)
-	    set_string_option_global(opt_idx, varp);
+	    set_string_option_global(idx, varp);
 
-	options[opt_idx].flags |= P_ALLOCED;
+	options[idx].flags |= P_ALLOCED;
 
 	/* When setting both values of a global option with a local value,
 	 * make the local value empty, so that the global value is used. */
-	if (((int)options[opt_idx].indir & PV_BOTH) && both)
+	if (((int)options[idx].indir & PV_BOTH) && both)
 	{
 	    free_string_option(*varp);
 	    *varp = empty_option;
 	}
 # ifdef FEAT_EVAL
 	if (set_sid != SID_NONE)
-	    set_option_scriptID_idx(opt_idx, opt_flags,
+	    set_option_scriptID_idx(idx, opt_flags,
 					set_sid == 0 ? current_SID : set_sid);
 # endif
     }
@@ -6325,7 +6326,8 @@
 	    else
 		errmsg = check_stl_option(p_ruf);
 	}
-	else
+	/* check 'statusline' only if it doesn't start with "%!" */
+	else if (varp != &p_stl || s[0] != '%' || s[1] != '!')
 	    errmsg = check_stl_option(s);
 	if (varp == &p_ruf && errmsg == NULL)
 	    comp_col();
@@ -7324,9 +7326,8 @@
 #ifdef FEAT_AUTOCHDIR
     else if ((int *)varp == &p_acd)
     {
-	if (p_acd && curbuf->b_ffname != NULL
-				     && vim_chdirfile(curbuf->b_ffname) == OK)
-	    shorten_fnames(TRUE);
+	/* Change directories when the 'acd' option is set now. */
+	DO_AUTOCHDIR
     }
 #endif
 
diff -Naur vim70.orig/src/os_unix.c vim70/src/os_unix.c
--- vim70.orig/src/os_unix.c	2006-05-01 01:13:15.000000000 -0700
+++ vim70/src/os_unix.c	2006-11-29 16:09:58.000000000 -0800
@@ -3934,7 +3934,7 @@
 		    {
 			linenr_T    lnum = curbuf->b_op_start.lnum;
 			int	    written = 0;
-			char_u	    *p = ml_get(lnum);
+			char_u	    *lp = ml_get(lnum);
 			char_u	    *s;
 			size_t	    l;
 
@@ -3942,17 +3942,17 @@
 			close(fromshell_fd);
 			for (;;)
 			{
-			    l = STRLEN(p + written);
+			    l = STRLEN(lp + written);
 			    if (l == 0)
 				len = 0;
-			    else if (p[written] == NL)
+			    else if (lp[written] == NL)
 				/* NL -> NUL translation */
 				len = write(toshell_fd, "", (size_t)1);
 			    else
 			    {
-				s = vim_strchr(p + written, NL);
-				len = write(toshell_fd, (char *)p + written,
-					   s == NULL ? l : s - (p + written));
+				s = vim_strchr(lp + written, NL);
+				len = write(toshell_fd, (char *)lp + written,
+					   s == NULL ? l : s - (lp + written));
 			    }
 			    if (len == l)
 			    {
@@ -3973,7 +3973,7 @@
 				    toshell_fd = -1;
 				    break;
 				}
-				p = ml_get(lnum);
+				lp = ml_get(lnum);
 				written = 0;
 			    }
 			    else if (len > 0)
@@ -5757,8 +5757,13 @@
     int		retval_int = 0;
     int		success = FALSE;
 
-    /* Get a handle to the DLL module. */
+    /*
+     * Get a handle to the DLL module.
+     */
 # if defined(USE_DLOPEN)
+    /* First clear any error, it's not cleared by the dlopen() call. */
+    (void)dlerror();
+
     hinstLib = dlopen((char *)libname, RTLD_LAZY
 #  ifdef RTLD_LOCAL
 	    | RTLD_LOCAL
diff -Naur vim70.orig/src/popupmnu.c vim70/src/popupmnu.c
--- vim70.orig/src/popupmnu.c	2006-04-20 13:18:37.000000000 -0700
+++ vim70/src/popupmnu.c	2006-11-29 16:09:57.000000000 -0800
@@ -552,6 +552,9 @@
 {
     pum_array = NULL;
     redraw_all_later(SOME_VALID);
+#ifdef FEAT_WINDOWS
+    redraw_tabline = TRUE;
+#endif
     status_redraw_all();
 }
 
diff -Naur vim70.orig/src/proto/buffer.pro vim70/src/proto/buffer.pro
--- vim70.orig/src/proto/buffer.pro	2006-05-07 06:08:29.000000000 -0700
+++ vim70/src/proto/buffer.pro	2006-11-29 16:10:04.000000000 -0800
@@ -10,6 +10,7 @@
 extern int do_buffer __ARGS((int action, int start, int dir, int count, int forceit));
 extern void set_curbuf __ARGS((buf_T *buf, int action));
 extern void enter_buffer __ARGS((buf_T *buf));
+extern void do_autochdir __ARGS((void));
 extern buf_T *buflist_new __ARGS((char_u *ffname, char_u *sfname, linenr_T lnum, int flags));
 extern void free_buf_options __ARGS((buf_T *buf, int free_p_ff));
 extern int buflist_getfile __ARGS((int n, linenr_T lnum, int options, int forceit));
diff -Naur vim70.orig/src/proto/eval.pro vim70/src/proto/eval.pro
--- vim70.orig/src/proto/eval.pro	2006-05-07 06:08:33.000000000 -0700
+++ vim70/src/proto/eval.pro	2006-11-29 16:10:10.000000000 -0800
@@ -44,7 +44,7 @@
 extern char_u *get_user_var_name __ARGS((expand_T *xp, int idx));
 extern list_T *list_alloc __ARGS((void));
 extern void list_unref __ARGS((list_T *l));
-extern void list_free __ARGS((list_T *l));
+extern void list_free __ARGS((list_T *l, int recurse));
 extern dictitem_T *dict_lookup __ARGS((hashitem_T *hi));
 extern int list_append_dict __ARGS((list_T *list, dict_T *dict));
 extern int garbage_collect __ARGS((void));
diff -Naur vim70.orig/src/proto/menu.pro vim70/src/proto/menu.pro
--- vim70.orig/src/proto/menu.pro	2006-05-07 06:08:51.000000000 -0700
+++ vim70/src/proto/menu.pro	2006-11-29 16:09:56.000000000 -0800
@@ -10,6 +10,7 @@
 extern int menu_is_child_of_popup __ARGS((vimmenu_T *menu));
 extern int menu_is_toolbar __ARGS((char_u *name));
 extern int menu_is_separator __ARGS((char_u *name));
+extern int check_menu_pointer __ARGS((vimmenu_T *root, vimmenu_T *menu_to_check));
 extern void gui_create_initial_menus __ARGS((vimmenu_T *menu));
 extern void gui_update_menus __ARGS((int modes));
 extern int gui_is_menu_shortcut __ARGS((int key));
diff -Naur vim70.orig/src/proto/misc2.pro vim70/src/proto/misc2.pro
--- vim70.orig/src/proto/misc2.pro	2006-05-07 06:08:54.000000000 -0700
+++ vim70/src/proto/misc2.pro	2006-11-29 16:10:08.000000000 -0800
@@ -29,6 +29,7 @@
 extern char_u *vim_strnsave __ARGS((char_u *string, int len));
 extern char_u *vim_strsave_escaped __ARGS((char_u *string, char_u *esc_chars));
 extern char_u *vim_strsave_escaped_ext __ARGS((char_u *string, char_u *esc_chars, int cc, int bsl));
+extern char_u *vim_strsave_shellescape __ARGS((char_u *string));
 extern char_u *vim_strsave_up __ARGS((char_u *string));
 extern char_u *vim_strnsave_up __ARGS((char_u *string, int len));
 extern void vim_strup __ARGS((char_u *p));
diff -Naur vim70.orig/src/proto/ops.pro vim70/src/proto/ops.pro
--- vim70.orig/src/proto/ops.pro	2006-05-07 06:08:58.000000000 -0700
+++ vim70/src/proto/ops.pro	2006-11-29 16:10:15.000000000 -0800
@@ -17,10 +17,10 @@
 extern void put_register __ARGS((int name, void *reg));
 extern int yank_register_mline __ARGS((int regname));
 extern int do_record __ARGS((int c));
-extern int do_execreg __ARGS((int regname, int colon, int addcr));
+extern int do_execreg __ARGS((int regname, int colon, int addcr, int silent));
 extern int insert_reg __ARGS((int regname, int literally));
 extern int get_spec_reg __ARGS((int regname, char_u **argp, int *allocated, int errmsg));
-extern int cmdline_paste_reg __ARGS((int regname, int literally));
+extern int cmdline_paste_reg __ARGS((int regname, int literally, int remcr));
 extern void adjust_clip_reg __ARGS((int *rp));
 extern int op_delete __ARGS((oparg_T *oap));
 extern int op_replace __ARGS((oparg_T *oap, int c));
diff -Naur vim70.orig/src/proto/undo.pro vim70/src/proto/undo.pro
--- vim70.orig/src/proto/undo.pro	2006-05-07 06:09:11.000000000 -0700
+++ vim70/src/proto/undo.pro	2006-11-29 16:09:53.000000000 -0800
@@ -4,6 +4,7 @@
 extern int u_savesub __ARGS((linenr_T lnum));
 extern int u_inssub __ARGS((linenr_T lnum));
 extern int u_savedel __ARGS((linenr_T lnum, long nlines));
+extern int undo_allowed __ARGS((void));
 extern void u_undo __ARGS((int count));
 extern void u_redo __ARGS((int count));
 extern void undo_time __ARGS((long step, int sec, int absolute));
diff -Naur vim70.orig/src/quickfix.c vim70/src/quickfix.c
--- vim70.orig/src/quickfix.c	2006-05-03 00:47:42.000000000 -0700
+++ vim70/src/quickfix.c	2006-11-29 16:10:12.000000000 -0800
@@ -500,8 +500,6 @@
 	{
 	    if (tv != NULL)
 	    {
-		int len;
-
 		if (tv->v_type == VAR_STRING)
 		{
 		    /* Get the next line from the supplied string */
@@ -602,13 +600,19 @@
 		else
 		    type = 0;
 		/*
-		 * Extract error message data from matched line
+		 * Extract error message data from matched line.
+		 * We check for an actual submatch, because "\[" and "\]" in
+		 * the 'errorformat' may cause the wrong submatch to be used.
 		 */
 		if ((i = (int)fmt_ptr->addr[0]) > 0)		/* %f */
 		{
-		    int c = *regmatch.endp[i];
+		    int c;
+
+		    if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL)
+			continue;
 
 		    /* Expand ~/file and $HOME/file to full path. */
+		    c = *regmatch.endp[i];
 		    *regmatch.endp[i] = NUL;
 		    expand_env(regmatch.startp[i], namebuf, CMDBUFFSIZE);
 		    *regmatch.endp[i] = c;
@@ -618,35 +622,63 @@
 			continue;
 		}
 		if ((i = (int)fmt_ptr->addr[1]) > 0)		/* %n */
+		{
+		    if (regmatch.startp[i] == NULL)
+			continue;
 		    enr = (int)atol((char *)regmatch.startp[i]);
+		}
 		if ((i = (int)fmt_ptr->addr[2]) > 0)		/* %l */
+		{
+		    if (regmatch.startp[i] == NULL)
+			continue;
 		    lnum = atol((char *)regmatch.startp[i]);
+		}
 		if ((i = (int)fmt_ptr->addr[3]) > 0)		/* %c */
+		{
+		    if (regmatch.startp[i] == NULL)
+			continue;
 		    col = (int)atol((char *)regmatch.startp[i]);
+		}
 		if ((i = (int)fmt_ptr->addr[4]) > 0)		/* %t */
+		{
+		    if (regmatch.startp[i] == NULL)
+			continue;
 		    type = *regmatch.startp[i];
+		}
 		if (fmt_ptr->flags == '+' && !multiscan)	/* %+ */
 		    STRCPY(errmsg, IObuff);
 		else if ((i = (int)fmt_ptr->addr[5]) > 0)	/* %m */
 		{
+		    if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL)
+			continue;
 		    len = (int)(regmatch.endp[i] - regmatch.startp[i]);
 		    vim_strncpy(errmsg, regmatch.startp[i], len);
 		}
 		if ((i = (int)fmt_ptr->addr[6]) > 0)		/* %r */
+		{
+		    if (regmatch.startp[i] == NULL)
+			continue;
 		    tail = regmatch.startp[i];
+		}
 		if ((i = (int)fmt_ptr->addr[7]) > 0)		/* %p */
 		{
+		    if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL)
+			continue;
 		    col = (int)(regmatch.endp[i] - regmatch.startp[i] + 1);
 		    if (*((char_u *)regmatch.startp[i]) != TAB)
 			use_viscol = TRUE;
 		}
 		if ((i = (int)fmt_ptr->addr[8]) > 0)		/* %v */
 		{
+		    if (regmatch.startp[i] == NULL)
+			continue;
 		    col = (int)atol((char *)regmatch.startp[i]);
 		    use_viscol = TRUE;
 		}
 		if ((i = (int)fmt_ptr->addr[9]) > 0)		/* %s */
 		{
+		    if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL)
+			continue;
 		    len = (int)(regmatch.endp[i] - regmatch.startp[i]);
 		    if (len > CMDBUFFSIZE - 5)
 			len = CMDBUFFSIZE - 5;
@@ -1554,10 +1586,30 @@
 	    }
 
 	/*
-	 * If there is only one window, create a new one above the quickfix
-	 * window.
+	 * If no usable window is found and 'switchbuf' is set to 'usetab'
+	 * then search in other tabs.
 	 */
-	if (firstwin == lastwin || !usable_win)
+	if (!usable_win && vim_strchr(p_swb, 'a') != NULL)
+	{
+	    tabpage_T	*tp;
+	    win_T	*wp;
+
+	    FOR_ALL_TAB_WINDOWS(tp, wp)
+	    {
+		if (wp->w_buffer->b_fnum == qf_ptr->qf_fnum)
+		{
+		    goto_tabpage_win(tp, wp);
+		    usable_win = 1;
+		    break;
+		}
+	    }
+	}
+
+	/*
+	 * If there is only one window and is the quickfix window, create a new
+	 * one above the quickfix window.
+	 */
+	if (((firstwin == lastwin) && bt_quickfix(curbuf)) || !usable_win)
 	{
 	    ll_ref = curwin->w_llist_ref;
 
@@ -2429,32 +2481,19 @@
     qf_info_T	*qi;
 {
     buf_T	*buf;
-#ifdef FEAT_AUTOCMD
     aco_save_T	aco;
-#else
-    buf_T	*save_curbuf;
-#endif
 
     /* Check if a buffer for the quickfix list exists.  Update it. */
     buf = qf_find_buf(qi);
     if (buf != NULL)
     {
-#ifdef FEAT_AUTOCMD
 	/* set curwin/curbuf to buf and save a few things */
 	aucmd_prepbuf(&aco, buf);
-#else
-	save_curbuf = curbuf;
-	curbuf = buf;
-#endif
 
 	qf_fill_buffer(qi);
 
-#ifdef FEAT_AUTOCMD
 	/* restore curwin/curbuf and a few other things */
 	aucmd_restbuf(&aco);
-#else
-	curbuf = save_curbuf;
-#endif
 
 	(void)qf_win_pos_update(qi, 0);
     }
@@ -2943,10 +2982,8 @@
 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
     char_u	*save_ei = NULL;
 #endif
-#ifndef FEAT_AUTOCMD
-    buf_T	*save_curbuf;
-#else
     aco_save_T	aco;
+#ifdef FEAT_AUTOCMD
     char_u	*au_name =  NULL;
     int		flags = 0;
     colnr_T	col;
@@ -3167,24 +3204,13 @@
 		     * need to be done now, in that buffer.  And the modelines
 		     * need to be done (again).  But not the window-local
 		     * options! */
-#if defined(FEAT_AUTOCMD)
 		    aucmd_prepbuf(&aco, buf);
-#else
-		    save_curbuf = curbuf;
-		    curbuf = buf;
-		    curwin->w_buffer = curbuf;
-#endif
 #if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
 		    apply_autocmds(EVENT_FILETYPE, buf->b_p_ft,
 						     buf->b_fname, TRUE, buf);
 #endif
 		    do_modelines(OPT_NOWIN);
-#if defined(FEAT_AUTOCMD)
 		    aucmd_restbuf(&aco);
-#else
-		    curbuf = save_curbuf;
-		    curwin->w_buffer = curbuf;
-#endif
 		}
 	    }
 	}
@@ -3285,11 +3311,7 @@
 {
     buf_T	*newbuf;
     int		failed = TRUE;
-#ifdef FEAT_AUTOCMD
     aco_save_T	aco;
-#else
-    buf_T	*old_curbuf = curbuf;
-#endif
 
     /* Allocate a buffer without putting it in the buffer list. */
     newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
@@ -3299,13 +3321,8 @@
     /* Init the options. */
     buf_copy_options(newbuf, BCO_ENTER | BCO_NOHELP);
 
-#ifdef FEAT_AUTOCMD
     /* set curwin/curbuf to buf and save a few things */
     aucmd_prepbuf(&aco, newbuf);
-#else
-    curbuf = newbuf;
-    curwin->w_buffer = newbuf;
-#endif
 
     /* Need to set the filename for autocommands. */
     (void)setfname(curbuf, fname, NULL, FALSE);
@@ -3336,13 +3353,8 @@
 	}
     }
 
-#ifdef FEAT_AUTOCMD
     /* restore curwin/curbuf and a few other things */
     aucmd_restbuf(&aco);
-#else
-    curbuf = old_curbuf;
-    curwin->w_buffer = old_curbuf;
-#endif
 
     if (!buf_valid(newbuf))
 	return NULL;
@@ -3434,8 +3446,10 @@
 	  || dict_add_nr_str(dict, "col",   (long)qfp->qf_col, NULL) == FAIL
 	  || dict_add_nr_str(dict, "vcol",  (long)qfp->qf_viscol, NULL) == FAIL
 	  || dict_add_nr_str(dict, "nr",    (long)qfp->qf_nr, NULL) == FAIL
-	  || dict_add_nr_str(dict, "pattern",  0L, qfp->qf_pattern) == FAIL
-	  || dict_add_nr_str(dict, "text",  0L, qfp->qf_text) == FAIL
+	  || dict_add_nr_str(dict, "pattern",  0L,
+	     qfp->qf_pattern == NULL ? (char_u *)"" : qfp->qf_pattern) == FAIL
+	  || dict_add_nr_str(dict, "text",  0L,
+		   qfp->qf_text == NULL ? (char_u *)"" : qfp->qf_text) == FAIL
 	  || dict_add_nr_str(dict, "type",  0L, buf) == FAIL
 	  || dict_add_nr_str(dict, "valid", (long)qfp->qf_valid, NULL) == FAIL)
 	    return FAIL;
diff -Naur vim70.orig/src/regexp.c vim70/src/regexp.c
--- vim70.orig/src/regexp.c	2006-04-30 08:31:50.000000000 -0700
+++ vim70/src/regexp.c	2006-11-29 16:10:12.000000000 -0800
@@ -3777,8 +3777,8 @@
 
 	op = OP(scan);
 	/* Check for character class with NL added. */
-	if (!reg_line_lbr && WITH_NL(op) && *reginput == NUL
-						    && reglnum <= reg_maxline)
+	if (!reg_line_lbr && WITH_NL(op) && REG_MULTI
+				&& *reginput == NUL && reglnum <= reg_maxline)
 	{
 	    reg_nextline();
 	}
@@ -3912,7 +3912,7 @@
 		{
 		    colnr_T	    start, end;
 		    colnr_T	    start2, end2;
-		    colnr_T	    col;
+		    colnr_T	    cols;
 
 		    getvvcol(wp, &top, &start, NULL, &end);
 		    getvvcol(wp, &bot, &start2, NULL, &end2);
@@ -3922,9 +3922,9 @@
 			end = end2;
 		    if (top.col == MAXCOL || bot.col == MAXCOL)
 			end = MAXCOL;
-		    col = win_linetabsize(wp,
+		    cols = win_linetabsize(wp,
 				      regline, (colnr_T)(reginput - regline));
-		    if (col < start || col > end - (*p_sel == 'e'))
+		    if (cols < start || cols > end - (*p_sel == 'e'))
 			status = RA_NOMATCH;
 		}
 	    }
@@ -4253,7 +4253,7 @@
 	    {
 		int	i, len;
 		char_u	*opnd;
-		int	opndc, inpc;
+		int	opndc = 0, inpc;
 
 		opnd = OPERAND(scan);
 		/* Safety check (just in case 'encoding' was changed since
@@ -4855,8 +4855,8 @@
 	    break;
 
 	  case NEWL:
-	    if ((c != NUL || reglnum > reg_maxline || reg_line_lbr)
-					      && (c != '\n' || !reg_line_lbr))
+	    if ((c != NUL || !REG_MULTI || reglnum > reg_maxline
+			     || reg_line_lbr) && (c != '\n' || !reg_line_lbr))
 		status = RA_NOMATCH;
 	    else if (reg_line_lbr)
 		ADVANCE_REGINPUT();
@@ -5316,8 +5316,8 @@
 		++count;
 		mb_ptr_adv(scan);
 	    }
-	    if (!WITH_NL(OP(p)) || reglnum > reg_maxline || reg_line_lbr
-							 || count == maxcount)
+	    if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+					 || reg_line_lbr || count == maxcount)
 		break;
 	    ++count;		/* count the line-break */
 	    reg_nextline();
@@ -5341,7 +5341,8 @@
 	    }
 	    else if (*scan == NUL)
 	    {
-		if (!WITH_NL(OP(p)) || reglnum > reg_maxline || reg_line_lbr)
+		if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+							      || reg_line_lbr)
 		    break;
 		reg_nextline();
 		scan = reginput;
@@ -5370,7 +5371,8 @@
 	    }
 	    else if (*scan == NUL)
 	    {
-		if (!WITH_NL(OP(p)) || reglnum > reg_maxline || reg_line_lbr)
+		if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+							      || reg_line_lbr)
 		    break;
 		reg_nextline();
 		scan = reginput;
@@ -5399,7 +5401,8 @@
 	    }
 	    else if (*scan == NUL)
 	    {
-		if (!WITH_NL(OP(p)) || reglnum > reg_maxline || reg_line_lbr)
+		if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+							      || reg_line_lbr)
 		    break;
 		reg_nextline();
 		scan = reginput;
@@ -5424,7 +5427,8 @@
 	{
 	    if (*scan == NUL)
 	    {
-		if (!WITH_NL(OP(p)) || reglnum > reg_maxline || reg_line_lbr)
+		if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+							      || reg_line_lbr)
 		    break;
 		reg_nextline();
 		scan = reginput;
@@ -5454,7 +5458,8 @@
 #endif
 	    if (*scan == NUL)
 	    {
-		if (!WITH_NL(OP(p)) || reglnum > reg_maxline || reg_line_lbr)
+		if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+							      || reg_line_lbr)
 		    break;
 		reg_nextline();
 		scan = reginput;
@@ -5617,7 +5622,8 @@
 #endif
 	    if (*scan == NUL)
 	    {
-		if (!WITH_NL(OP(p)) || reglnum > reg_maxline || reg_line_lbr)
+		if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
+							      || reg_line_lbr)
 		    break;
 		reg_nextline();
 		scan = reginput;
@@ -5646,8 +5652,8 @@
 
       case NEWL:
 	while (count < maxcount
-		&& ((*scan == NUL && reglnum <= reg_maxline && !reg_line_lbr)
-		    || (*scan == '\n' && reg_line_lbr)))
+		&& ((*scan == NUL && reglnum <= reg_maxline && !reg_line_lbr
+			    && REG_MULTI) || (*scan == '\n' && reg_line_lbr)))
 	{
 	    count++;
 	    if (reg_line_lbr)
diff -Naur vim70.orig/src/screen.c vim70/src/screen.c
--- vim70.orig/src/screen.c	2006-05-05 03:13:55.000000000 -0700
+++ vim70/src/screen.c	2006-11-29 16:10:15.000000000 -0800
@@ -455,6 +455,7 @@
 		    && curwin->w_topline == curwin->w_lines[0].wl_lnum)
 #ifdef FEAT_VISUAL
 		|| (type == INVERTED
+		    && VIsual_active
 		    && curwin->w_old_cursor_lnum == curwin->w_cursor.lnum
 		    && curwin->w_old_visual_mode == VIsual_mode
 		    && (curwin->w_valid & VALID_VIRTCOL)
@@ -1228,7 +1229,14 @@
 	{
 	    mid_end = wp->w_height;
 	    if (lastwin == firstwin)
+	    {
 		screenclear();
+#ifdef FEAT_WINDOWS
+		/* The screen was cleared, redraw the tab pages line. */
+		if (redraw_tabline)
+		    draw_tabline();
+#endif
+	    }
 	}
     }
     else
@@ -2612,7 +2620,8 @@
 #ifdef FEAT_LINEBREAK
     int		need_showbreak = FALSE;
 #endif
-#if defined(FEAT_SIGNS) || (defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS))
+#if defined(FEAT_SIGNS) || (defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS)) \
+	|| defined(FEAT_SYN_HL) || defined(FEAT_DIFF)
 # define LINE_ATTR
     int		line_attr = 0;		/* atrribute for the whole line */
 #endif
@@ -2626,7 +2635,7 @@
     int		prev_c = 0;		/* previous Arabic character */
     int		prev_c1 = 0;		/* first composing char for prev_c */
 #endif
-#if defined(FEAT_DIFF) || defined(LINE_ATTR)
+#if defined(LINE_ATTR)
     int		did_line_attr = 0;
 #endif
 
@@ -4116,17 +4125,12 @@
 		    --ptr;	    /* put it back at the NUL */
 		}
 #endif
-#if defined(FEAT_DIFF) || defined(LINE_ATTR)
+#if defined(LINE_ATTR)
 		else if ((
 # ifdef FEAT_DIFF
-			    diff_hlf != (hlf_T)0
-#  ifdef LINE_ATTR
-			    ||
-#  endif
+			    diff_hlf != (hlf_T)0 ||
 # endif
-# ifdef LINE_ATTR
 			    line_attr != 0
-# endif
 			) && (
 # ifdef FEAT_RIGHTLEFT
 			    wp->w_p_rl ? (col >= 0) :
@@ -4237,7 +4241,7 @@
 	 * At end of the text line or just after the last character.
 	 */
 	if (c == NUL
-#if defined(FEAT_DIFF) || defined(LINE_ATTR)
+#if defined(LINE_ATTR)
 		|| did_line_attr == 1
 #endif
 		)
@@ -4258,7 +4262,7 @@
 				|| prevcol == (long)match_hl[0].startcol
 				|| prevcol == (long)match_hl[1].startcol
 				|| prevcol == (long)match_hl[2].startcol)
-# if defined(FEAT_DIFF) || defined(LINE_ATTR)
+# if defined(LINE_ATTR)
 			    && did_line_attr <= 1
 # endif
 			   )
@@ -5076,15 +5080,38 @@
 	     * character too.  If we didn't skip any blanks above, then we
 	     * only redraw if the character wasn't already redrawn anyway.
 	     */
-	    if (gui.in_use && (col > startCol || !redraw_this)
-# ifdef FEAT_MBYTE
-		    && enc_dbcs == 0
-# endif
-	       )
+	    if (gui.in_use && (col > startCol || !redraw_this))
 	    {
 		hl = ScreenAttrs[off_to];
 		if (hl > HL_ALL || (hl & HL_BOLD))
-		    screen_char(off_to - 1, row, col + coloff - 1);
+		{
+		    int prev_cells = 1;
+# ifdef FEAT_MBYTE
+		    if (enc_utf8)
+			/* for utf-8, ScreenLines[char_offset + 1] == 0 means
+			 * that its width is 2. */
+			prev_cells = ScreenLines[off_to - 1] == 0 ? 2 : 1;
+		    else if (enc_dbcs != 0)
+		    {
+			/* find previous character by counting from first
+			 * column and get its width. */
+			unsigned off = LineOffset[row];
+
+			while (off < off_to)
+			{
+			    prev_cells = (*mb_off2cells)(off);
+			    off += prev_cells;
+			}
+		    }
+
+		    if (enc_dbcs != 0 && prev_cells > 1)
+			screen_char_2(off_to - prev_cells, row,
+						   col + coloff - prev_cells);
+		    else
+# endif
+			screen_char(off_to - prev_cells, row,
+						   col + coloff - prev_cells);
+		}
 	    }
 #endif
 	    screen_fill(row, row + 1, col + coloff, clear_width + coloff,
@@ -7103,7 +7130,7 @@
     tabpage_T	    *tp;
 #endif
     static int	    entered = FALSE;		/* avoid recursiveness */
-    static int	    did_outofmem_msg = FALSE;	/* did outofmem message */
+    static int	    done_outofmem_msg = FALSE;	/* did outofmem message */
 
     /*
      * Allocation of the screen buffers is done only when the size changes and
@@ -7133,6 +7160,12 @@
 	return;
     entered = TRUE;
 
+    /*
+     * Note that the window sizes are updated before reallocating the arrays,
+     * thus we must not redraw here!
+     */
+    ++RedrawingDisabled;
+
     win_new_shellsize();    /* fit the windows in the new sized shell */
 
     comp_col();		/* recompute columns for shown command and ruler */
@@ -7205,14 +7238,14 @@
 #endif
 	    || outofmem)
     {
-	if (ScreenLines != NULL || !did_outofmem_msg)
+	if (ScreenLines != NULL || !done_outofmem_msg)
 	{
 	    /* guess the size */
 	    do_outofmem_msg((long_u)((Rows + 1) * Columns));
 
 	    /* Remember we did this to avoid getting outofmem messages over
 	     * and over again. */
-	    did_outofmem_msg = TRUE;
+	    done_outofmem_msg = TRUE;
 	}
 	vim_free(new_ScreenLines);
 	new_ScreenLines = NULL;
@@ -7240,7 +7273,7 @@
     }
     else
     {
-	did_outofmem_msg = FALSE;
+	done_outofmem_msg = FALSE;
 
 	for (new_row = 0; new_row < Rows; ++new_row)
 	{
@@ -7367,6 +7400,7 @@
 #endif
 
     entered = FALSE;
+    --RedrawingDisabled;
 
 #ifdef FEAT_AUTOCMD
     if (starting == 0)
diff -Naur vim70.orig/src/search.c vim70/src/search.c
--- vim70.orig/src/search.c	2006-05-05 05:12:13.000000000 -0700
+++ vim70/src/search.c	2006-11-29 16:10:10.000000000 -0800
@@ -1259,7 +1259,7 @@
 	/*
 	 * Add character and/or line offset
 	 */
-	if (!(options & SEARCH_NOOF) || *pat == ';')
+	if (!(options & SEARCH_NOOF) || (pat != NULL && *pat == ';'))
 	{
 	    if (spats[0].off.line)	/* Add the offset to the line number. */
 	    {
@@ -4688,6 +4688,7 @@
 #ifdef FEAT_INS_EXPAND
 		    if (action == ACTION_EXPAND)
 		    {
+			msg_hist_off = TRUE;	/* reset in msg_trunc_attr() */
 			vim_snprintf((char*)IObuff, IOSIZE,
 				_("Scanning included file: %s"),
 				(char *)new_fname);
@@ -4826,15 +4827,20 @@
 
 		if ((compl_cont_status & CONT_ADDING) && i == compl_length)
 		{
-		    /* get the next line */
 		    /* IOSIZE > compl_length, so the STRNCPY works */
 		    STRNCPY(IObuff, aux, i);
-		    if (!(     depth < 0
-			    && lnum < end_lnum
-			    && (line = ml_get(++lnum)) != NULL)
-			&& !(	depth >= 0
-			    && !vim_fgets(line = file_line,
-						     LSIZE, files[depth].fp)))
+
+		    /* Get the next line: when "depth" < 0  from the current
+		     * buffer, otherwise from the included file.  Jump to
+		     * exit_matched when past the last line. */
+		    if (depth < 0)
+		    {
+			if (lnum >= end_lnum)
+			    goto exit_matched;
+			line = ml_get(++lnum);
+		    }
+		    else if (vim_fgets(line = file_line,
+						      LSIZE, files[depth].fp))
 			goto exit_matched;
 
 		    /* we read a line, set "already" to check this "line" later
@@ -4871,7 +4877,7 @@
 			goto exit_matched;
 		}
 
-		add_r = ins_compl_add_infercase(aux, i, FALSE,
+		add_r = ins_compl_add_infercase(aux, i, p_ic,
 			curr_fname == curbuf->b_fname ? NULL : curr_fname,
 			dir, reuse);
 		if (add_r == OK)
diff -Naur vim70.orig/src/spell.c vim70/src/spell.c
--- vim70.orig/src/spell.c	2006-05-05 00:49:58.000000000 -0700
+++ vim70/src/spell.c	2006-11-29 16:10:06.000000000 -0800
@@ -1483,7 +1483,7 @@
 	    else if ((mode == FIND_COMPOUND || mode == FIND_KEEPCOMPOUND
 								|| !word_ends))
 	    {
-		/* If there is no  flag or the word is shorter than
+		/* If there is no compound flag or the word is shorter than
 		 * COMPOUNDMIN reject it quickly.
 		 * Makes you wonder why someone puts a compound flag on a word
 		 * that's too short...  Myspell compatibility requires this
@@ -2043,8 +2043,8 @@
     int		len;
 # ifdef FEAT_SYN_HL
     int		has_syntax = syntax_present(wp->w_buffer);
-    int		col;
 # endif
+    int		col;
     int		can_spell;
     char_u	*buf = NULL;
     int		buflen = 0;
@@ -2093,9 +2093,8 @@
 	    capcol = (int)(skipwhite(line) - line);
 	else if (curline && wp == curwin)
 	{
-	    int	    col = (int)(skipwhite(line) - line);
-
 	    /* For spellbadword(): check if first word needs a capital. */
+	    col = (int)(skipwhite(line) - line);
 	    if (check_need_cap(lnum, col))
 		capcol = col;
 
@@ -2108,7 +2107,8 @@
 	 * possible. */
 	STRCPY(buf, line);
 	if (lnum < wp->w_buffer->b_ml.ml_line_count)
-	    spell_cat_line(buf + STRLEN(buf), ml_get(lnum + 1), MAXWLEN);
+	    spell_cat_line(buf + STRLEN(buf),
+			  ml_get_buf(wp->w_buffer, lnum + 1, FALSE), MAXWLEN);
 
 	p = buf + skip;
 	endp = buf + len;
@@ -5060,7 +5060,7 @@
     int		do_rep;
     int		do_repsal;
     int		do_sal;
-    int		do_map;
+    int		do_mapline;
     int		found_map = FALSE;
     hashitem_T	*hi;
     int		l;
@@ -5098,7 +5098,7 @@
     do_sal = spin->si_sal.ga_len == 0;
 
     /* Only do MAP lines when not done in another .aff file already. */
-    do_map = spin->si_map.ga_len == 0;
+    do_mapline = spin->si_map.ga_len == 0;
 
     /*
      * Allocate and init the afffile_T structure.
@@ -5780,7 +5780,7 @@
 			smsg((char_u *)_("Expected MAP count in %s line %d"),
 								 fname, lnum);
 		}
-		else if (do_map)
+		else if (do_mapline)
 		{
 		    int		c;
 
@@ -7507,7 +7507,7 @@
 {
     char_u	*p = p_msm;
     long	start = 0;
-    long	inc = 0;
+    long	incr = 0;
     long	added = 0;
 
     if (!VIM_ISDIGIT(*p))
@@ -7519,7 +7519,7 @@
     ++p;
     if (!VIM_ISDIGIT(*p))
 	return FAIL;
-    inc = (getdigits(&p) * 102) / (SBLOCKSIZE / 10);
+    incr = (getdigits(&p) * 102) / (SBLOCKSIZE / 10);
     if (*p != ',')
 	return FAIL;
     ++p;
@@ -7529,11 +7529,11 @@
     if (*p != NUL)
 	return FAIL;
 
-    if (start == 0 || inc == 0 || added == 0 || inc > start)
+    if (start == 0 || incr == 0 || added == 0 || incr > start)
 	return FAIL;
 
     compress_start = start;
-    compress_inc = inc;
+    compress_inc = incr;
     compress_added = added;
     return OK;
 }
@@ -8291,14 +8291,14 @@
  * Returns the number of nodes used.
  */
     static int
-put_node(fd, node, index, regionmask, prefixtree)
+put_node(fd, node, idx, regionmask, prefixtree)
     FILE	*fd;		/* NULL when only counting */
     wordnode_T	*node;
-    int		index;
+    int		idx;
     int		regionmask;
     int		prefixtree;	/* TRUE for PREFIXTREE */
 {
-    int		newindex = index;
+    int		newindex = idx;
     int		siblingcount = 0;
     wordnode_T	*np;
     int		flags;
@@ -8308,7 +8308,7 @@
 	return 0;
 
     /* Store the index where this node is written. */
-    node->wn_u1.index = index;
+    node->wn_u1.index = idx;
 
     /* Count the number of siblings. */
     for (np = node; np != NULL; np = np->wn_sibling)
@@ -9243,15 +9243,15 @@
  * Add "word[len]" to 'spellfile' as a good or bad word.
  */
     void
-spell_add_word(word, len, bad, index, undo)
+spell_add_word(word, len, bad, idx, undo)
     char_u	*word;
     int		len;
     int		bad;
-    int		index;	    /* "zG" and "zW": zero, otherwise index in
+    int		idx;	    /* "zG" and "zW": zero, otherwise index in
 			       'spellfile' */
     int		undo;	    /* TRUE for "zug", "zuG", "zuw" and "zuW" */
 {
-    FILE	*fd;
+    FILE	*fd = NULL;
     buf_T	*buf = NULL;
     int		new_spf = FALSE;
     char_u	*fname;
@@ -9261,7 +9261,7 @@
     int		i;
     char_u	*spf;
 
-    if (index == 0)	    /* use internal wordlist */
+    if (idx == 0)	    /* use internal wordlist */
     {
 	if (int_wordlist == NULL)
 	{
@@ -9289,11 +9289,11 @@
 	for (spf = curbuf->b_p_spf, i = 1; *spf != NUL; ++i)
 	{
 	    copy_option_part(&spf, fnamebuf, MAXPATHL, ",");
-	    if (i == index)
+	    if (i == idx)
 		break;
 	    if (*spf == NUL)
 	    {
-		EMSGN(_("E765: 'spellfile' does not have %ld entries"), index);
+		EMSGN(_("E765: 'spellfile' does not have %ld entries"), idx);
 		return;
 	    }
 	}
@@ -9336,7 +9336,10 @@
 		    {
 			fputc('#', fd);
 			if (undo)
+			{
+			    home_replace(NULL, fname, NameBuff, MAXPATHL, TRUE);
 			    smsg((char_u *)_("Word removed from %s"), NameBuff);
+			}
 		    }
 		    fseek(fd, fpos_next, SEEK_SET);
 		}
@@ -9344,20 +9347,27 @@
 	    fclose(fd);
 	}
     }
-    else
+
+    if (!undo)
     {
 	fd = mch_fopen((char *)fname, "a");
 	if (fd == NULL && new_spf)
 	{
+	    char_u *p;
+
 	    /* We just initialized the 'spellfile' option and can't open the
 	     * file.  We may need to create the "spell" directory first.  We
 	     * already checked the runtime directory is writable in
 	     * init_spellfile(). */
-	    if (!dir_of_file_exists(fname))
+	    if (!dir_of_file_exists(fname) && (p = gettail_sep(fname)) != fname)
 	    {
+		int c = *p;
+
 		/* The directory doesn't exist.  Try creating it and opening
 		 * the file again. */
-		vim_mkdir(NameBuff, 0755);
+		*p = NUL;
+		vim_mkdir(fname, 0755);
+		*p = c;
 		fd = mch_fopen((char *)fname, "a");
 	    }
 	}
@@ -10070,6 +10080,7 @@
 
 	/* List the suggestions. */
 	msg_start();
+	msg_row = Rows - 1;	/* for when 'cmdheight' > 1 */
 	lines_left = Rows;	/* avoid more prompt */
 	vim_snprintf((char *)IObuff, IOSIZE, _("Change \"%.*s\" to:"),
 						sug.su_badlen, sug.su_badptr);
@@ -13579,53 +13590,58 @@
 	 * the first "the" to itself. */
 	return;
 
-    /* Check if the word is already there.  Also check the length that is
-     * being replaced "thes," -> "these" is a different suggestion from
-     * "thes" -> "these". */
-    stp = &SUG(*gap, 0);
-    for (i = gap->ga_len; --i >= 0; ++stp)
-	if (stp->st_wordlen == goodlen
-		&& stp->st_orglen == badlen
-		&& STRNCMP(stp->st_word, goodword, goodlen) == 0)
-	{
-	    /*
-	     * Found it.  Remember the word with the lowest score.
-	     */
-	    if (stp->st_slang == NULL)
-		stp->st_slang = slang;
+    if (gap->ga_len == 0)
+	i = -1;
+    else
+    {
+	/* Check if the word is already there.  Also check the length that is
+	 * being replaced "thes," -> "these" is a different suggestion from
+	 * "thes" -> "these". */
+	stp = &SUG(*gap, 0);
+	for (i = gap->ga_len; --i >= 0; ++stp)
+	    if (stp->st_wordlen == goodlen
+		    && stp->st_orglen == badlen
+		    && STRNCMP(stp->st_word, goodword, goodlen) == 0)
+	    {
+		/*
+		 * Found it.  Remember the word with the lowest score.
+		 */
+		if (stp->st_slang == NULL)
+		    stp->st_slang = slang;
 
-	    new_sug.st_score = score;
-	    new_sug.st_altscore = altscore;
-	    new_sug.st_had_bonus = had_bonus;
+		new_sug.st_score = score;
+		new_sug.st_altscore = altscore;
+		new_sug.st_had_bonus = had_bonus;
+
+		if (stp->st_had_bonus != had_bonus)
+		{
+		    /* Only one of the two had the soundalike score computed.
+		     * Need to do that for the other one now, otherwise the
+		     * scores can't be compared.  This happens because
+		     * suggest_try_change() doesn't compute the soundalike
+		     * word to keep it fast, while some special methods set
+		     * the soundalike score to zero. */
+		    if (had_bonus)
+			rescore_one(su, stp);
+		    else
+		    {
+			new_sug.st_word = stp->st_word;
+			new_sug.st_wordlen = stp->st_wordlen;
+			new_sug.st_slang = stp->st_slang;
+			new_sug.st_orglen = badlen;
+			rescore_one(su, &new_sug);
+		    }
+		}
 
-	    if (stp->st_had_bonus != had_bonus)
-	    {
-		/* Only one of the two had the soundalike score computed.
-		 * Need to do that for the other one now, otherwise the
-		 * scores can't be compared.  This happens because
-		 * suggest_try_change() doesn't compute the soundalike
-		 * word to keep it fast, while some special methods set
-		 * the soundalike score to zero. */
-		if (had_bonus)
-		    rescore_one(su, stp);
-		else
+		if (stp->st_score > new_sug.st_score)
 		{
-		    new_sug.st_word = stp->st_word;
-		    new_sug.st_wordlen = stp->st_wordlen;
-		    new_sug.st_slang = stp->st_slang;
-		    new_sug.st_orglen = badlen;
-		    rescore_one(su, &new_sug);
+		    stp->st_score = new_sug.st_score;
+		    stp->st_altscore = new_sug.st_altscore;
+		    stp->st_had_bonus = new_sug.st_had_bonus;
 		}
+		break;
 	    }
-
-	    if (stp->st_score > new_sug.st_score)
-	    {
-		stp->st_score = new_sug.st_score;
-		stp->st_altscore = new_sug.st_altscore;
-		stp->st_had_bonus = new_sug.st_had_bonus;
-	    }
-	    break;
-	}
+    }
 
     if (i < 0 && ga_grow(gap, 1) == OK)
     {
@@ -15656,7 +15672,7 @@
 		    ? MB_STRNICMP(p, pat, STRLEN(pat)) == 0
 		    : STRNCMP(p, pat, STRLEN(pat)) == 0)
 		&& ins_compl_add_infercase(p, (int)STRLEN(p),
-					  FALSE, NULL, *dir, 0) == OK)
+					  p_ic, NULL, *dir, 0) == OK)
 	/* if dir was BACKWARD then honor it just once */
 	*dir = FORWARD;
 }
diff -Naur vim70.orig/src/structs.h vim70/src/structs.h
--- vim70.orig/src/structs.h	2006-04-09 10:57:46.000000000 -0700
+++ vim70/src/structs.h	2006-11-29 16:09:56.000000000 -0800
@@ -2213,18 +2213,20 @@
 
 /*
  * Struct to save values in before executing autocommands for a buffer that is
- * not the current buffer.
+ * not the current buffer.  Without FEAT_AUTOCMD only "curbuf" is remembered.
  */
 typedef struct
 {
     buf_T	*save_buf;	/* saved curbuf */
+#ifdef FEAT_AUTOCMD
     buf_T	*new_curbuf;	/* buffer to be used */
     win_T	*save_curwin;	/* saved curwin, NULL if it didn't change */
     win_T	*new_curwin;	/* new curwin if save_curwin != NULL */
     pos_T	save_cursor;	/* saved cursor pos of save_curwin */
     linenr_T	save_topline;	/* saved topline of save_curwin */
-#ifdef FEAT_DIFF
+# ifdef FEAT_DIFF
     int		save_topfill;	/* saved topfill of save_curwin */
+# endif
 #endif
 } aco_save_T;
 
diff -Naur vim70.orig/src/syntax.c vim70/src/syntax.c
--- vim70.orig/src/syntax.c	2006-04-26 05:49:45.000000000 -0700
+++ vim70/src/syntax.c	2006-11-29 16:10:14.000000000 -0800
@@ -977,6 +977,7 @@
 {
     stateitem_T	*cur_si;
     int		i;
+    int		seen_keepend;
 
     if (startofline)
     {
@@ -1002,7 +1003,10 @@
     /*
      * Need to update the end of a start/skip/end that continues from the
      * previous line.  And regions that have "keepend", because they may
-     * influence contained items.
+     * influence contained items.  If we've just removed "extend"
+     * (startofline == 0) then we should update ends of normal regions
+     * contained inside "keepend" because "extend" could have extended
+     * these "keepend" regions as well as contained normal regions.
      * Then check for items ending in column 0.
      */
     i = current_state.ga_len - 1;
@@ -1010,10 +1014,13 @@
 	for ( ; i > keepend_level; --i)
 	    if (CUR_STATE(i).si_flags & HL_EXTEND)
 		break;
+
+    seen_keepend = FALSE;
     for ( ; i < current_state.ga_len; ++i)
     {
 	cur_si = &CUR_STATE(i);
 	if ((cur_si->si_flags & HL_KEEPEND)
+			    || (seen_keepend && !startofline)
 			    || (i == current_state.ga_len - 1 && startofline))
 	{
 	    cur_si->si_h_startpos.col = 0;	/* start highl. in col 0 */
@@ -1021,6 +1028,9 @@
 
 	    if (!(cur_si->si_flags & HL_MATCHCONT))
 		update_si_end(cur_si, (int)current_col, !startofline);
+
+	    if (!startofline && (cur_si->si_flags & HL_KEEPEND))
+		seen_keepend = TRUE;
 	}
     }
     check_keepend();
@@ -2564,6 +2574,7 @@
 {
     int		i;
     lpos_T	maxpos;
+    lpos_T	maxpos_h;
     stateitem_T	*sip;
 
     /*
@@ -2583,23 +2594,30 @@
 	    break;
 
     maxpos.lnum = 0;
+    maxpos_h.lnum = 0;
     for ( ; i < current_state.ga_len; ++i)
     {
 	sip = &CUR_STATE(i);
 	if (maxpos.lnum != 0)
 	{
 	    limit_pos_zero(&sip->si_m_endpos, &maxpos);
-	    limit_pos_zero(&sip->si_h_endpos, &maxpos);
+	    limit_pos_zero(&sip->si_h_endpos, &maxpos_h);
 	    limit_pos_zero(&sip->si_eoe_pos, &maxpos);
 	    sip->si_ends = TRUE;
 	}
-	if (sip->si_ends
-		&& (sip->si_flags & HL_KEEPEND)
-		&& (maxpos.lnum == 0
+	if (sip->si_ends && (sip->si_flags & HL_KEEPEND))
+	{
+	    if (maxpos.lnum == 0
 		    || maxpos.lnum > sip->si_m_endpos.lnum
 		    || (maxpos.lnum == sip->si_m_endpos.lnum
-			&& maxpos.col > sip->si_m_endpos.col)))
-	    maxpos = sip->si_m_endpos;
+			&& maxpos.col > sip->si_m_endpos.col))
+		maxpos = sip->si_m_endpos;
+	    if (maxpos_h.lnum == 0
+		    || maxpos_h.lnum > sip->si_h_endpos.lnum
+		    || (maxpos_h.lnum == sip->si_h_endpos.lnum
+			&& maxpos_h.col > sip->si_h_endpos.col))
+		maxpos_h = sip->si_h_endpos;
+	}
     }
 }
 
@@ -6054,7 +6072,11 @@
 		++level;
     }
     if (level > wp->w_p_fdn)
+    {
 	level = wp->w_p_fdn;
+	if (level < 0)
+	    level = 0;
+    }
     return level;
 }
 #endif
diff -Naur vim70.orig/src/tag.c vim70/src/tag.c
--- vim70.orig/src/tag.c	2006-04-27 06:11:21.000000000 -0700
+++ vim70/src/tag.c	2006-11-29 16:10:10.000000000 -0800
@@ -911,7 +911,7 @@
 
 		set_errorlist(curwin, list, ' ');
 
-		list_free(list);
+		list_free(list, TRUE);
 
 		cur_match = 0;		/* Jump to the first tag */
 	    }
@@ -3787,6 +3787,7 @@
 {
     int		num_matches, i, ret;
     char_u	**matches, *p;
+    char_u	*full_fname;
     dict_T	*dict;
     tagptrs_T	tp;
     long	is_static;
@@ -3809,9 +3810,10 @@
 	    if (list_append_dict(list, dict) == FAIL)
 		ret = FAIL;
 
+	    full_fname = tag_full_fname(&tp);
 	    if (add_tag_field(dict, "name", tp.tagname, tp.tagname_end) == FAIL
-		    || add_tag_field(dict, "filename", tp.fname,
-							 tp.fname_end) == FAIL
+		    || add_tag_field(dict, "filename", full_fname,
+							 NULL) == FAIL
 		    || add_tag_field(dict, "cmd", tp.command,
 						       tp.command_end) == FAIL
 		    || add_tag_field(dict, "kind", tp.tagkind,
@@ -3819,6 +3821,8 @@
 		    || dict_add_nr_str(dict, "static", is_static, NULL) == FAIL)
 		ret = FAIL;
 
+	    vim_free(full_fname);
+
 	    if (tp.command_end != NULL)
 	    {
 		for (p = tp.command_end + 3;
diff -Naur vim70.orig/src/term.c vim70/src/term.c
--- vim70.orig/src/term.c	2006-05-03 10:34:57.000000000 -0700
+++ vim70/src/term.c	2006-11-29 16:10:13.000000000 -0800
@@ -3137,25 +3137,32 @@
 	    screenalloc(FALSE);
 	    repeat_message();
 	}
-	else if (State & CMDLINE)
-	{
-	    update_screen(NOT_VALID);
-	    redrawcmdline();
-	}
 	else
 	{
-	    update_topline();
-#if defined(FEAT_INS_EXPAND)
-	    if (pum_visible())
+#ifdef FEAT_SCROLLBIND
+	    if (curwin->w_p_scb)
+		do_check_scrollbind(TRUE);
+#endif
+	    if (State & CMDLINE)
 	    {
-		redraw_later(NOT_VALID);
-		ins_compl_show_pum(); /* This includes the redraw. */
+		update_screen(NOT_VALID);
+		redrawcmdline();
 	    }
 	    else
+	    {
+		update_topline();
+#if defined(FEAT_INS_EXPAND)
+		if (pum_visible())
+		{
+		    redraw_later(NOT_VALID);
+		    ins_compl_show_pum(); /* This includes the redraw. */
+		}
+		else
 #endif
-		update_screen(NOT_VALID);
-	    if (redrawing())
-		setcursor();
+		    update_screen(NOT_VALID);
+		if (redrawing())
+		    setcursor();
+	    }
 	}
 	cursor_on();	    /* redrawing may have switched it off */
     }
@@ -4783,6 +4790,14 @@
 		return -1;
 	    current_menu = (vimmenu_T *)val;
 	    slen += num_bytes;
+
+	    /* The menu may have been deleted right after it was used, check
+	     * for that. */
+	    if (check_menu_pointer(root_menu, current_menu) == FAIL)
+	    {
+		key_name[0] = KS_EXTRA;
+		key_name[1] = (int)KE_IGNORE;
+	    }
 	}
 # endif
 # ifdef FEAT_GUI_TABLINE
diff -Naur vim70.orig/src/testdir/test56.in vim70/src/testdir/test56.in
--- vim70.orig/src/testdir/test56.in	2005-05-18 08:37:37.000000000 -0700
+++ vim70/src/testdir/test56.in	2006-11-29 16:10:03.000000000 -0800
@@ -3,7 +3,7 @@
 STARTTEST
 :so small.vim
 :"
-:set nocp
+:set nocp viminfo+=nviminfo
 :/^start:/+1,/^end:/-1w! Xtest.vim
 :source Xtest.vim
 _x
diff -Naur vim70.orig/src/ui.c vim70/src/ui.c
--- vim70.orig/src/ui.c	2006-03-27 11:15:09.000000000 -0800
+++ vim70/src/ui.c	2006-11-29 16:09:59.000000000 -0800
@@ -1137,7 +1137,6 @@
     int		len;
 #ifdef FEAT_MBYTE
     char_u	*p;
-    int		i;
 #endif
     int		row1 = clip_star.start.lnum;
     int		col1 = clip_star.start.col;
@@ -1218,6 +1217,8 @@
 #ifdef FEAT_MBYTE
 	    if (enc_dbcs != 0)
 	    {
+		int	i;
+
 		p = ScreenLines + LineOffset[row];
 		for (i = start_col; i < end_col; ++i)
 		    if (enc_dbcs == DBCS_JPNU && p[i] == 0x8e)
diff -Naur vim70.orig/src/undo.c vim70/src/undo.c
--- vim70.orig/src/undo.c	2006-04-21 02:30:59.000000000 -0700
+++ vim70/src/undo.c	2006-11-29 16:09:59.000000000 -0800
@@ -84,7 +84,6 @@
 static void u_unch_branch __ARGS((u_header_T *uhp));
 static u_entry_T *u_get_headentry __ARGS((void));
 static void u_getbot __ARGS((void));
-static int undo_allowed __ARGS((void));
 static int u_savecommon __ARGS((linenr_T, linenr_T, linenr_T));
 static void u_doit __ARGS((int count));
 static void u_undoredo __ARGS((int undo));
@@ -196,7 +195,7 @@
  * Return TRUE when undo is allowed.  Otherwise give an error message and
  * return FALSE.
  */
-    static int
+    int
 undo_allowed()
 {
     /* Don't allow changes when 'modifiable' is off.  */
@@ -1188,7 +1187,7 @@
     int		did_undo;	/* just did an undo */
     int		absolute;	/* used ":undo N" */
 {
-    char	*msg;
+    char	*msgstr;
     u_header_T	*uhp;
     char_u	msgbuf[80];
 
@@ -1206,20 +1205,20 @@
 
     u_oldcount -= u_newcount;
     if (u_oldcount == -1)
-	msg = N_("more line");
+	msgstr = N_("more line");
     else if (u_oldcount < 0)
-	msg = N_("more lines");
+	msgstr = N_("more lines");
     else if (u_oldcount == 1)
-	msg = N_("line less");
+	msgstr = N_("line less");
     else if (u_oldcount > 1)
-	msg = N_("fewer lines");
+	msgstr = N_("fewer lines");
     else
     {
 	u_oldcount = u_newcount;
 	if (u_newcount == 1)
-	    msg = N_("change");
+	    msgstr = N_("change");
 	else
-	    msg = N_("changes");
+	    msgstr = N_("changes");
     }
 
     if (curbuf->b_u_curhead != NULL)
@@ -1245,7 +1244,7 @@
 
     smsg((char_u *)_("%ld %s; %s #%ld  %s"),
 	    u_oldcount < 0 ? -u_oldcount : u_oldcount,
-	    _(msg),
+	    _(msgstr),
 	    did_undo ? _("before") : _("after"),
 	    uhp == NULL ? 0L : uhp->uh_seq,
 	    msgbuf);
diff -Naur vim70.orig/src/version.c vim70/src/version.c
--- vim70.orig/src/version.c	2006-05-03 00:50:42.000000000 -0700
+++ vim70/src/version.c	2006-11-29 16:10:24.000000000 -0800
@@ -667,6 +667,320 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    174,
+/**/
+    173,
+/**/
+    172,
+/**/
+    169,
+/**/
+    168,
+/**/
+    167,
+/**/
+    166,
+/**/
+    165,
+/**/
+    164,
+/**/
+    163,
+/**/
+    162,
+/**/
+    160,
+/**/
+    159,
+/**/
+    158,
+/**/
+    157,
+/**/
+    155,
+/**/
+    154,
+/**/
+    153,
+/**/
+    152,
+/**/
+    151,
+/**/
+    150,
+/**/
+    149,
+/**/
+    148,
+/**/
+    147,
+/**/
+    146,
+/**/
+    145,
+/**/
+    144,
+/**/
+    143,
+/**/
+    142,
+/**/
+    141,
+/**/
+    140,
+/**/
+    139,
+/**/
+    137,
+/**/
+    136,
+/**/
+    135,
+/**/
+    134,
+/**/
+    133,
+/**/
+    129,
+/**/
+    128,
+/**/
+    127,
+/**/
+    126,
+/**/
+    125,
+/**/
+    124,
+/**/
+    123,
+/**/
+    122,
+/**/
+    121,
+/**/
+    120,
+/**/
+    119,
+/**/
+    118,
+/**/
+    117,
+/**/
+    116,
+/**/
+    115,
+/**/
+    114,
+/**/
+    113,
+/**/
+    112,
+/**/
+    111,
+/**/
+    110,
+/**/
+    109,
+/**/
+    107,
+/**/
+    106,
+/**/
+    105,
+/**/
+    104,
+/**/
+    103,
+/**/
+    102,
+/**/
+    101,
+/**/
+    100,
+/**/
+    99,
+/**/
+    98,
+/**/
+    97,
+/**/
+    96,
+/**/
+    95,
+/**/
+    94,
+/**/
+    93,
+/**/
+    92,
+/**/
+    91,
+/**/
+    90,
+/**/
+    89,
+/**/
+    88,
+/**/
+    87,
+/**/
+    86,
+/**/
+    85,
+/**/
+    84,
+/**/
+    83,
+/**/
+    82,
+/**/
+    81,
+/**/
+    80,
+/**/
+    79,
+/**/
+    78,
+/**/
+    77,
+/**/
+    76,
+/**/
+    75,
+/**/
+    73,
+/**/
+    72,
+/**/
+    71,
+/**/
+    70,
+/**/
+    69,
+/**/
+    68,
+/**/
+    67,
+/**/
+    66,
+/**/
+    64,
+/**/
+    63,
+/**/
+    62,
+/**/
+    61,
+/**/
+    60,
+/**/
+    59,
+/**/
+    58,
+/**/
+    56,
+/**/
+    55,
+/**/
+    54,
+/**/
+    53,
+/**/
+    52,
+/**/
+    51,
+/**/
+    50,
+/**/
+    49,
+/**/
+    48,
+/**/
+    47,
+/**/
+    46,
+/**/
+    44,
+/**/
+    43,
+/**/
+    42,
+/**/
+    41,
+/**/
+    40,
+/**/
+    39,
+/**/
+    38,
+/**/
+    37,
+/**/
+    36,
+/**/
+    35,
+/**/
+    34,
+/**/
+    33,
+/**/
+    31,
+/**/
+    30,
+/**/
+    29,
+/**/
+    26,
+/**/
+    25,
+/**/
+    24,
+/**/
+    23,
+/**/
+    22,
+/**/
+    21,
+/**/
+    20,
+/**/
+    19,
+/**/
+    18,
+/**/
+    17,
+/**/
+    16,
+/**/
+    15,
+/**/
+    14,
+/**/
+    13,
+/**/
+    12,
+/**/
+    11,
+/**/
+    10,
+/**/
+    9,
+/**/
+    8,
+/**/
+    7,
+/**/
+    6,
+/**/
+    4,
+/**/
+    3,
+/**/
+    2,
+/**/
+    1,
+/**/
     0
 };
 
@@ -731,7 +1045,11 @@
     /* Only MS VC 4.1 and earlier can do Win32s */
     MSG_PUTS(_("\nMS-Windows 16/32 bit GUI version"));
 #  else
+#   ifdef _WIN64
+    MSG_PUTS(_("\nMS-Windows 64 bit GUI version"));
+#   else
     MSG_PUTS(_("\nMS-Windows 32 bit GUI version"));
+#   endif
 #  endif
     if (gui_is_win32s())
 	MSG_PUTS(_(" in Win32s mode"));
diff -Naur vim70.orig/src/vim.h vim70/src/vim.h
--- vim70.orig/src/vim.h	2006-04-30 08:32:38.000000000 -0700
+++ vim70/src/vim.h	2006-11-29 16:10:14.000000000 -0800
@@ -585,7 +585,6 @@
 #define INSERT		0x10	/* Insert mode */
 #define LANGMAP		0x20	/* Language mapping, can be combined with
 				   INSERT and CMDLINE */
-#define MAP_ALL_MODES	0x3f	/* all mode bits used for mapping */
 
 #define REPLACE_FLAG	0x40	/* Replace mode flag */
 #define REPLACE		(REPLACE_FLAG + INSERT)
@@ -605,6 +604,9 @@
 #define CONFIRM		0x800	/* ":confirm" prompt */
 #define SELECTMODE	0x1000	/* Select mode, only for mappings */
 
+#define MAP_ALL_MODES	(0x3f | SELECTMODE)	/* all mode bits used for
+						 * mapping */
+
 /* directions */
 #define FORWARD			1
 #define BACKWARD		(-1)
@@ -1118,6 +1120,7 @@
     EVENT_FOCUSGAINED,		/* got the focus */
     EVENT_FOCUSLOST,		/* lost the focus to another app */
     EVENT_GUIENTER,		/* after starting the GUI */
+    EVENT_GUIFAILED,		/* after starting the GUI failed */
     EVENT_INSERTCHANGE,		/* when changing Insert/Replace mode */
     EVENT_INSERTENTER,		/* when entering Insert mode */
     EVENT_INSERTLEAVE,		/* when leaving Insert mode */
@@ -1666,7 +1669,10 @@
 #define VV_SWAPCHOICE	46
 #define VV_SWAPCOMMAND	47
 #define VV_CHAR		48
-#define VV_LEN		49	/* number of v: vars */
+#define VV_MOUSE_WIN	49
+#define VV_MOUSE_LNUM   50
+#define VV_MOUSE_COL	51
+#define VV_LEN		52	/* number of v: vars */
 
 #ifdef FEAT_CLIPBOARD
 
diff -Naur vim70.orig/src/window.c vim70/src/window.c
--- vim70.orig/src/window.c	2006-05-06 03:54:51.000000000 -0700
+++ vim70/src/window.c	2006-11-29 16:10:15.000000000 -0800
@@ -340,10 +340,10 @@
 		{
 		    tabpage_T	*oldtab = curtab;
 		    tabpage_T	*newtab;
-		    win_T	*wp = curwin;
 
 		    /* First create a new tab with the window, then go back to
 		     * the old tab and close the window there. */
+		    wp = curwin;
 		    if (win_new_tabpage((int)Prenum) == OK
 						     && valid_tabpage(oldtab))
 		    {
@@ -3954,13 +3954,8 @@
     setmouse();			/* in case jumped to/from help buffer */
 #endif
 
-#ifdef FEAT_AUTOCHDIR
-    /* Change directories when the 'acd' option is set on and after
-     * switching windows. */
-    if (p_acd && curbuf->b_ffname != NULL
-				     && vim_chdirfile(curbuf->b_ffname) == OK)
-	shorten_fnames(TRUE);
-#endif
+    /* Change directories when the 'acd' option is set. */
+    DO_AUTOCHDIR
 }
 
 #endif /* FEAT_WINDOWS */
@@ -4278,7 +4273,7 @@
     win_T	*wp;
 {
     wp->w_lines_valid = 0;
-    wp->w_lines = (wline_T *)alloc((unsigned)(Rows * sizeof(wline_T)));
+    wp->w_lines = (wline_T *)alloc_clear((unsigned)(Rows * sizeof(wline_T)));
     if (wp->w_lines == NULL)
 	return FAIL;
     return OK;
@@ -5194,11 +5189,7 @@
     int		height;
 {
     linenr_T	lnum;
-    linenr_T	bot;
     int		sline, line_size;
-    int		space;
-    int		did_below = FALSE;
-    int		old_height = wp->w_height;
 #define FRACTION_MULT	16384L
 
     /* Don't want a negative height.  Happens when splitting a tiny window.
@@ -5233,54 +5224,44 @@
 	wp->w_wrow = ((long)wp->w_fraction * (long)height - 1L) / FRACTION_MULT;
 	line_size = plines_win_col(wp, lnum, (long)(wp->w_cursor.col)) - 1;
 	sline = wp->w_wrow - line_size;
+
+	if (sline >= 0)
+	{
+	    /* Make sure the whole cursor line is visible, if possible. */
+	    int rows = plines_win(wp, lnum, FALSE);
+
+	    if (sline > wp->w_height - rows)
+	    {
+		sline = wp->w_height - rows;
+		wp->w_wrow -= rows - line_size;
+	    }
+	}
+
 	if (sline < 0)
 	{
 	    /*
 	     * Cursor line would go off top of screen if w_wrow was this high.
+	     * Make cursor line the first line in the window.  If not enough
+	     * room use w_skipcol;
 	     */
 	    wp->w_wrow = line_size;
+	    if (wp->w_wrow >= wp->w_height
+				       && (W_WIDTH(wp) - win_col_off(wp)) > 0)
+	    {
+		wp->w_skipcol += W_WIDTH(wp) - win_col_off(wp);
+		--wp->w_wrow;
+		while (wp->w_wrow >= wp->w_height)
+		{
+		    wp->w_skipcol += W_WIDTH(wp) - win_col_off(wp)
+							   + win_col_off2(wp);
+		    --wp->w_wrow;
+		}
+	    }
 	}
 	else
 	{
-	    space = height - 1;
-
-	    while (lnum > 1)
+	    while (sline > 0 && lnum > 1)
 	    {
-		/* When using "~" lines stop when at the old topline, don't
-		 * scroll down. */
-		if (did_below && height < old_height && lnum <= wp->w_topline)
-		    sline = 0;
-
-		space -= line_size;
-		if (space > 0 && sline <= 0 && !did_below)
-		{
-		    /* Try to use "~" lines below the text to avoid that text
-		     * is above the window while there are empty lines.
-		     * Subtract the rows below the cursor from "space" and
-		     * give the rest to "sline". */
-		    did_below = TRUE;
-		    bot = wp->w_cursor.lnum;
-		    while (space > 0)
-		    {
-			if (wp->w_buffer->b_ml.ml_line_count - bot >= space)
-			    space = 0;
-			else
-			{
-#ifdef FEAT_FOLDING
-			    hasFoldingWin(wp, bot, NULL, &bot, TRUE, NULL);
-#endif
-			    if (bot >= wp->w_buffer->b_ml.ml_line_count)
-				break;
-			    ++bot;
-			    space -= plines_win(wp, bot, TRUE);
-			}
-		    }
-		    if (bot == wp->w_buffer->b_ml.ml_line_count && space > 0)
-			sline += space;
-		}
-		if (sline <= 0)
-		    break;
-
 #ifdef FEAT_FOLDING
 		hasFoldingWin(wp, lnum, &lnum, NULL, TRUE, NULL);
 		if (lnum == 1)
